diff options
| author | monster <[email protected]> | 2022-07-07 14:41:37 +0300 |
|---|---|---|
| committer | monster <[email protected]> | 2022-07-07 14:41:37 +0300 |
| commit | 06e5c21a835c0e923506c4ff27929f34e00761c2 (patch) | |
| tree | 75efcbc6854ef9bd476eb8bf00cc5c900da436a2 /contrib/tools/python3/src/Python | |
| parent | 03f024c4412e3aa613bb543cf1660176320ba8f4 (diff) | |
fix ya.make
Diffstat (limited to 'contrib/tools/python3/src/Python')
76 files changed, 0 insertions, 92333 deletions
diff --git a/contrib/tools/python3/src/Python/Python-ast.c b/contrib/tools/python3/src/Python/Python-ast.c deleted file mode 100644 index 2f84cad7749..00000000000 --- a/contrib/tools/python3/src/Python/Python-ast.c +++ /dev/null @@ -1,12057 +0,0 @@ -// File automatically generated by Parser/asdl_c.py. - -#include "Python.h" -#include "pycore_ast.h" -#include "pycore_ast_state.h" // struct ast_state -#include "pycore_interp.h" // _PyInterpreterState.ast -#include "pycore_pystate.h" // _PyInterpreterState_GET() -#include "structmember.h" -#include <stddef.h> - -// Forward declaration -static int init_types(struct ast_state *state); - -static struct ast_state* -get_ast_state(void) -{ - PyInterpreterState *interp = _PyInterpreterState_GET(); - struct ast_state *state = &interp->ast; - if (!init_types(state)) { - return NULL; - } - return state; -} - -void _PyAST_Fini(PyInterpreterState *interp) -{ - struct ast_state *state = &interp->ast; - - Py_CLEAR(state->AST_type); - Py_CLEAR(state->Add_singleton); - Py_CLEAR(state->Add_type); - Py_CLEAR(state->And_singleton); - Py_CLEAR(state->And_type); - Py_CLEAR(state->AnnAssign_type); - Py_CLEAR(state->Assert_type); - Py_CLEAR(state->Assign_type); - Py_CLEAR(state->AsyncFor_type); - Py_CLEAR(state->AsyncFunctionDef_type); - Py_CLEAR(state->AsyncWith_type); - Py_CLEAR(state->Attribute_type); - Py_CLEAR(state->AugAssign_type); - Py_CLEAR(state->Await_type); - Py_CLEAR(state->BinOp_type); - Py_CLEAR(state->BitAnd_singleton); - Py_CLEAR(state->BitAnd_type); - Py_CLEAR(state->BitOr_singleton); - Py_CLEAR(state->BitOr_type); - Py_CLEAR(state->BitXor_singleton); - Py_CLEAR(state->BitXor_type); - Py_CLEAR(state->BoolOp_type); - Py_CLEAR(state->Break_type); - Py_CLEAR(state->Call_type); - Py_CLEAR(state->ClassDef_type); - Py_CLEAR(state->Compare_type); - Py_CLEAR(state->Constant_type); - Py_CLEAR(state->Continue_type); - Py_CLEAR(state->Del_singleton); - Py_CLEAR(state->Del_type); - Py_CLEAR(state->Delete_type); - Py_CLEAR(state->DictComp_type); - Py_CLEAR(state->Dict_type); - Py_CLEAR(state->Div_singleton); - Py_CLEAR(state->Div_type); - Py_CLEAR(state->Eq_singleton); - Py_CLEAR(state->Eq_type); - Py_CLEAR(state->ExceptHandler_type); - Py_CLEAR(state->Expr_type); - Py_CLEAR(state->Expression_type); - Py_CLEAR(state->FloorDiv_singleton); - Py_CLEAR(state->FloorDiv_type); - Py_CLEAR(state->For_type); - Py_CLEAR(state->FormattedValue_type); - Py_CLEAR(state->FunctionDef_type); - Py_CLEAR(state->FunctionType_type); - Py_CLEAR(state->GeneratorExp_type); - Py_CLEAR(state->Global_type); - Py_CLEAR(state->GtE_singleton); - Py_CLEAR(state->GtE_type); - Py_CLEAR(state->Gt_singleton); - Py_CLEAR(state->Gt_type); - Py_CLEAR(state->IfExp_type); - Py_CLEAR(state->If_type); - Py_CLEAR(state->ImportFrom_type); - Py_CLEAR(state->Import_type); - Py_CLEAR(state->In_singleton); - Py_CLEAR(state->In_type); - Py_CLEAR(state->Interactive_type); - Py_CLEAR(state->Invert_singleton); - Py_CLEAR(state->Invert_type); - Py_CLEAR(state->IsNot_singleton); - Py_CLEAR(state->IsNot_type); - Py_CLEAR(state->Is_singleton); - Py_CLEAR(state->Is_type); - Py_CLEAR(state->JoinedStr_type); - Py_CLEAR(state->LShift_singleton); - Py_CLEAR(state->LShift_type); - Py_CLEAR(state->Lambda_type); - Py_CLEAR(state->ListComp_type); - Py_CLEAR(state->List_type); - Py_CLEAR(state->Load_singleton); - Py_CLEAR(state->Load_type); - Py_CLEAR(state->LtE_singleton); - Py_CLEAR(state->LtE_type); - Py_CLEAR(state->Lt_singleton); - Py_CLEAR(state->Lt_type); - Py_CLEAR(state->MatMult_singleton); - Py_CLEAR(state->MatMult_type); - Py_CLEAR(state->MatchAs_type); - Py_CLEAR(state->MatchClass_type); - Py_CLEAR(state->MatchMapping_type); - Py_CLEAR(state->MatchOr_type); - Py_CLEAR(state->MatchSequence_type); - Py_CLEAR(state->MatchSingleton_type); - Py_CLEAR(state->MatchStar_type); - Py_CLEAR(state->MatchValue_type); - Py_CLEAR(state->Match_type); - Py_CLEAR(state->Mod_singleton); - Py_CLEAR(state->Mod_type); - Py_CLEAR(state->Module_type); - Py_CLEAR(state->Mult_singleton); - Py_CLEAR(state->Mult_type); - Py_CLEAR(state->Name_type); - Py_CLEAR(state->NamedExpr_type); - Py_CLEAR(state->Nonlocal_type); - Py_CLEAR(state->NotEq_singleton); - Py_CLEAR(state->NotEq_type); - Py_CLEAR(state->NotIn_singleton); - Py_CLEAR(state->NotIn_type); - Py_CLEAR(state->Not_singleton); - Py_CLEAR(state->Not_type); - Py_CLEAR(state->Or_singleton); - Py_CLEAR(state->Or_type); - Py_CLEAR(state->Pass_type); - Py_CLEAR(state->Pow_singleton); - Py_CLEAR(state->Pow_type); - Py_CLEAR(state->RShift_singleton); - Py_CLEAR(state->RShift_type); - Py_CLEAR(state->Raise_type); - Py_CLEAR(state->Return_type); - Py_CLEAR(state->SetComp_type); - Py_CLEAR(state->Set_type); - Py_CLEAR(state->Slice_type); - Py_CLEAR(state->Starred_type); - Py_CLEAR(state->Store_singleton); - Py_CLEAR(state->Store_type); - Py_CLEAR(state->Sub_singleton); - Py_CLEAR(state->Sub_type); - Py_CLEAR(state->Subscript_type); - Py_CLEAR(state->Try_type); - Py_CLEAR(state->Tuple_type); - Py_CLEAR(state->TypeIgnore_type); - Py_CLEAR(state->UAdd_singleton); - Py_CLEAR(state->UAdd_type); - Py_CLEAR(state->USub_singleton); - Py_CLEAR(state->USub_type); - Py_CLEAR(state->UnaryOp_type); - Py_CLEAR(state->While_type); - Py_CLEAR(state->With_type); - Py_CLEAR(state->YieldFrom_type); - Py_CLEAR(state->Yield_type); - Py_CLEAR(state->__dict__); - Py_CLEAR(state->__doc__); - Py_CLEAR(state->__match_args__); - Py_CLEAR(state->__module__); - Py_CLEAR(state->_attributes); - Py_CLEAR(state->_fields); - Py_CLEAR(state->alias_type); - Py_CLEAR(state->annotation); - Py_CLEAR(state->arg); - Py_CLEAR(state->arg_type); - Py_CLEAR(state->args); - Py_CLEAR(state->argtypes); - Py_CLEAR(state->arguments_type); - Py_CLEAR(state->asname); - Py_CLEAR(state->ast); - Py_CLEAR(state->attr); - Py_CLEAR(state->bases); - Py_CLEAR(state->body); - Py_CLEAR(state->boolop_type); - Py_CLEAR(state->cases); - Py_CLEAR(state->cause); - Py_CLEAR(state->cls); - Py_CLEAR(state->cmpop_type); - Py_CLEAR(state->col_offset); - Py_CLEAR(state->comparators); - Py_CLEAR(state->comprehension_type); - Py_CLEAR(state->context_expr); - Py_CLEAR(state->conversion); - Py_CLEAR(state->ctx); - Py_CLEAR(state->decorator_list); - Py_CLEAR(state->defaults); - Py_CLEAR(state->elt); - Py_CLEAR(state->elts); - Py_CLEAR(state->end_col_offset); - Py_CLEAR(state->end_lineno); - Py_CLEAR(state->exc); - Py_CLEAR(state->excepthandler_type); - Py_CLEAR(state->expr_context_type); - Py_CLEAR(state->expr_type); - Py_CLEAR(state->finalbody); - Py_CLEAR(state->format_spec); - Py_CLEAR(state->func); - Py_CLEAR(state->generators); - Py_CLEAR(state->guard); - Py_CLEAR(state->handlers); - Py_CLEAR(state->id); - Py_CLEAR(state->ifs); - Py_CLEAR(state->is_async); - Py_CLEAR(state->items); - Py_CLEAR(state->iter); - Py_CLEAR(state->key); - Py_CLEAR(state->keys); - Py_CLEAR(state->keyword_type); - Py_CLEAR(state->keywords); - Py_CLEAR(state->kind); - Py_CLEAR(state->kw_defaults); - Py_CLEAR(state->kwarg); - Py_CLEAR(state->kwd_attrs); - Py_CLEAR(state->kwd_patterns); - Py_CLEAR(state->kwonlyargs); - Py_CLEAR(state->left); - Py_CLEAR(state->level); - Py_CLEAR(state->lineno); - Py_CLEAR(state->lower); - Py_CLEAR(state->match_case_type); - Py_CLEAR(state->mod_type); - Py_CLEAR(state->module); - Py_CLEAR(state->msg); - Py_CLEAR(state->name); - Py_CLEAR(state->names); - Py_CLEAR(state->op); - Py_CLEAR(state->operand); - Py_CLEAR(state->operator_type); - Py_CLEAR(state->ops); - Py_CLEAR(state->optional_vars); - Py_CLEAR(state->orelse); - Py_CLEAR(state->pattern); - Py_CLEAR(state->pattern_type); - Py_CLEAR(state->patterns); - Py_CLEAR(state->posonlyargs); - Py_CLEAR(state->rest); - Py_CLEAR(state->returns); - Py_CLEAR(state->right); - Py_CLEAR(state->simple); - Py_CLEAR(state->slice); - Py_CLEAR(state->step); - Py_CLEAR(state->stmt_type); - Py_CLEAR(state->subject); - Py_CLEAR(state->tag); - Py_CLEAR(state->target); - Py_CLEAR(state->targets); - Py_CLEAR(state->test); - Py_CLEAR(state->type); - Py_CLEAR(state->type_comment); - Py_CLEAR(state->type_ignore_type); - Py_CLEAR(state->type_ignores); - Py_CLEAR(state->unaryop_type); - Py_CLEAR(state->upper); - Py_CLEAR(state->value); - Py_CLEAR(state->values); - Py_CLEAR(state->vararg); - Py_CLEAR(state->withitem_type); - -#if !defined(NDEBUG) - state->initialized = -1; -#else - state->initialized = 0; -#endif -} - -static int init_identifiers(struct ast_state *state) -{ - if ((state->__dict__ = PyUnicode_InternFromString("__dict__")) == NULL) return 0; - if ((state->__doc__ = PyUnicode_InternFromString("__doc__")) == NULL) return 0; - if ((state->__match_args__ = PyUnicode_InternFromString("__match_args__")) == NULL) return 0; - if ((state->__module__ = PyUnicode_InternFromString("__module__")) == NULL) return 0; - if ((state->_attributes = PyUnicode_InternFromString("_attributes")) == NULL) return 0; - if ((state->_fields = PyUnicode_InternFromString("_fields")) == NULL) return 0; - if ((state->annotation = PyUnicode_InternFromString("annotation")) == NULL) return 0; - if ((state->arg = PyUnicode_InternFromString("arg")) == NULL) return 0; - if ((state->args = PyUnicode_InternFromString("args")) == NULL) return 0; - if ((state->argtypes = PyUnicode_InternFromString("argtypes")) == NULL) return 0; - if ((state->asname = PyUnicode_InternFromString("asname")) == NULL) return 0; - if ((state->ast = PyUnicode_InternFromString("ast")) == NULL) return 0; - if ((state->attr = PyUnicode_InternFromString("attr")) == NULL) return 0; - if ((state->bases = PyUnicode_InternFromString("bases")) == NULL) return 0; - if ((state->body = PyUnicode_InternFromString("body")) == NULL) return 0; - if ((state->cases = PyUnicode_InternFromString("cases")) == NULL) return 0; - if ((state->cause = PyUnicode_InternFromString("cause")) == NULL) return 0; - if ((state->cls = PyUnicode_InternFromString("cls")) == NULL) return 0; - if ((state->col_offset = PyUnicode_InternFromString("col_offset")) == NULL) return 0; - if ((state->comparators = PyUnicode_InternFromString("comparators")) == NULL) return 0; - if ((state->context_expr = PyUnicode_InternFromString("context_expr")) == NULL) return 0; - if ((state->conversion = PyUnicode_InternFromString("conversion")) == NULL) return 0; - if ((state->ctx = PyUnicode_InternFromString("ctx")) == NULL) return 0; - if ((state->decorator_list = PyUnicode_InternFromString("decorator_list")) == NULL) return 0; - if ((state->defaults = PyUnicode_InternFromString("defaults")) == NULL) return 0; - if ((state->elt = PyUnicode_InternFromString("elt")) == NULL) return 0; - if ((state->elts = PyUnicode_InternFromString("elts")) == NULL) return 0; - if ((state->end_col_offset = PyUnicode_InternFromString("end_col_offset")) == NULL) return 0; - if ((state->end_lineno = PyUnicode_InternFromString("end_lineno")) == NULL) return 0; - if ((state->exc = PyUnicode_InternFromString("exc")) == NULL) return 0; - if ((state->finalbody = PyUnicode_InternFromString("finalbody")) == NULL) return 0; - if ((state->format_spec = PyUnicode_InternFromString("format_spec")) == NULL) return 0; - if ((state->func = PyUnicode_InternFromString("func")) == NULL) return 0; - if ((state->generators = PyUnicode_InternFromString("generators")) == NULL) return 0; - if ((state->guard = PyUnicode_InternFromString("guard")) == NULL) return 0; - if ((state->handlers = PyUnicode_InternFromString("handlers")) == NULL) return 0; - if ((state->id = PyUnicode_InternFromString("id")) == NULL) return 0; - if ((state->ifs = PyUnicode_InternFromString("ifs")) == NULL) return 0; - if ((state->is_async = PyUnicode_InternFromString("is_async")) == NULL) return 0; - if ((state->items = PyUnicode_InternFromString("items")) == NULL) return 0; - if ((state->iter = PyUnicode_InternFromString("iter")) == NULL) return 0; - if ((state->key = PyUnicode_InternFromString("key")) == NULL) return 0; - if ((state->keys = PyUnicode_InternFromString("keys")) == NULL) return 0; - if ((state->keywords = PyUnicode_InternFromString("keywords")) == NULL) return 0; - if ((state->kind = PyUnicode_InternFromString("kind")) == NULL) return 0; - if ((state->kw_defaults = PyUnicode_InternFromString("kw_defaults")) == NULL) return 0; - if ((state->kwarg = PyUnicode_InternFromString("kwarg")) == NULL) return 0; - if ((state->kwd_attrs = PyUnicode_InternFromString("kwd_attrs")) == NULL) return 0; - if ((state->kwd_patterns = PyUnicode_InternFromString("kwd_patterns")) == NULL) return 0; - if ((state->kwonlyargs = PyUnicode_InternFromString("kwonlyargs")) == NULL) return 0; - if ((state->left = PyUnicode_InternFromString("left")) == NULL) return 0; - if ((state->level = PyUnicode_InternFromString("level")) == NULL) return 0; - if ((state->lineno = PyUnicode_InternFromString("lineno")) == NULL) return 0; - if ((state->lower = PyUnicode_InternFromString("lower")) == NULL) return 0; - if ((state->module = PyUnicode_InternFromString("module")) == NULL) return 0; - if ((state->msg = PyUnicode_InternFromString("msg")) == NULL) return 0; - if ((state->name = PyUnicode_InternFromString("name")) == NULL) return 0; - if ((state->names = PyUnicode_InternFromString("names")) == NULL) return 0; - if ((state->op = PyUnicode_InternFromString("op")) == NULL) return 0; - if ((state->operand = PyUnicode_InternFromString("operand")) == NULL) return 0; - if ((state->ops = PyUnicode_InternFromString("ops")) == NULL) return 0; - if ((state->optional_vars = PyUnicode_InternFromString("optional_vars")) == NULL) return 0; - if ((state->orelse = PyUnicode_InternFromString("orelse")) == NULL) return 0; - if ((state->pattern = PyUnicode_InternFromString("pattern")) == NULL) return 0; - if ((state->patterns = PyUnicode_InternFromString("patterns")) == NULL) return 0; - if ((state->posonlyargs = PyUnicode_InternFromString("posonlyargs")) == NULL) return 0; - if ((state->rest = PyUnicode_InternFromString("rest")) == NULL) return 0; - if ((state->returns = PyUnicode_InternFromString("returns")) == NULL) return 0; - if ((state->right = PyUnicode_InternFromString("right")) == NULL) return 0; - if ((state->simple = PyUnicode_InternFromString("simple")) == NULL) return 0; - if ((state->slice = PyUnicode_InternFromString("slice")) == NULL) return 0; - if ((state->step = PyUnicode_InternFromString("step")) == NULL) return 0; - if ((state->subject = PyUnicode_InternFromString("subject")) == NULL) return 0; - if ((state->tag = PyUnicode_InternFromString("tag")) == NULL) return 0; - if ((state->target = PyUnicode_InternFromString("target")) == NULL) return 0; - if ((state->targets = PyUnicode_InternFromString("targets")) == NULL) return 0; - if ((state->test = PyUnicode_InternFromString("test")) == NULL) return 0; - if ((state->type = PyUnicode_InternFromString("type")) == NULL) return 0; - if ((state->type_comment = PyUnicode_InternFromString("type_comment")) == NULL) return 0; - if ((state->type_ignores = PyUnicode_InternFromString("type_ignores")) == NULL) return 0; - if ((state->upper = PyUnicode_InternFromString("upper")) == NULL) return 0; - if ((state->value = PyUnicode_InternFromString("value")) == NULL) return 0; - if ((state->values = PyUnicode_InternFromString("values")) == NULL) return 0; - if ((state->vararg = PyUnicode_InternFromString("vararg")) == NULL) return 0; - return 1; -}; - -GENERATE_ASDL_SEQ_CONSTRUCTOR(mod, mod_ty) -GENERATE_ASDL_SEQ_CONSTRUCTOR(stmt, stmt_ty) -GENERATE_ASDL_SEQ_CONSTRUCTOR(expr, expr_ty) -GENERATE_ASDL_SEQ_CONSTRUCTOR(comprehension, comprehension_ty) -GENERATE_ASDL_SEQ_CONSTRUCTOR(excepthandler, excepthandler_ty) -GENERATE_ASDL_SEQ_CONSTRUCTOR(arguments, arguments_ty) -GENERATE_ASDL_SEQ_CONSTRUCTOR(arg, arg_ty) -GENERATE_ASDL_SEQ_CONSTRUCTOR(keyword, keyword_ty) -GENERATE_ASDL_SEQ_CONSTRUCTOR(alias, alias_ty) -GENERATE_ASDL_SEQ_CONSTRUCTOR(withitem, withitem_ty) -GENERATE_ASDL_SEQ_CONSTRUCTOR(match_case, match_case_ty) -GENERATE_ASDL_SEQ_CONSTRUCTOR(pattern, pattern_ty) -GENERATE_ASDL_SEQ_CONSTRUCTOR(type_ignore, type_ignore_ty) - -static PyObject* ast2obj_mod(struct ast_state *state, void*); -static const char * const Module_fields[]={ - "body", - "type_ignores", -}; -static const char * const Interactive_fields[]={ - "body", -}; -static const char * const Expression_fields[]={ - "body", -}; -static const char * const FunctionType_fields[]={ - "argtypes", - "returns", -}; -static const char * const stmt_attributes[] = { - "lineno", - "col_offset", - "end_lineno", - "end_col_offset", -}; -static PyObject* ast2obj_stmt(struct ast_state *state, void*); -static const char * const FunctionDef_fields[]={ - "name", - "args", - "body", - "decorator_list", - "returns", - "type_comment", -}; -static const char * const AsyncFunctionDef_fields[]={ - "name", - "args", - "body", - "decorator_list", - "returns", - "type_comment", -}; -static const char * const ClassDef_fields[]={ - "name", - "bases", - "keywords", - "body", - "decorator_list", -}; -static const char * const Return_fields[]={ - "value", -}; -static const char * const Delete_fields[]={ - "targets", -}; -static const char * const Assign_fields[]={ - "targets", - "value", - "type_comment", -}; -static const char * const AugAssign_fields[]={ - "target", - "op", - "value", -}; -static const char * const AnnAssign_fields[]={ - "target", - "annotation", - "value", - "simple", -}; -static const char * const For_fields[]={ - "target", - "iter", - "body", - "orelse", - "type_comment", -}; -static const char * const AsyncFor_fields[]={ - "target", - "iter", - "body", - "orelse", - "type_comment", -}; -static const char * const While_fields[]={ - "test", - "body", - "orelse", -}; -static const char * const If_fields[]={ - "test", - "body", - "orelse", -}; -static const char * const With_fields[]={ - "items", - "body", - "type_comment", -}; -static const char * const AsyncWith_fields[]={ - "items", - "body", - "type_comment", -}; -static const char * const Match_fields[]={ - "subject", - "cases", -}; -static const char * const Raise_fields[]={ - "exc", - "cause", -}; -static const char * const Try_fields[]={ - "body", - "handlers", - "orelse", - "finalbody", -}; -static const char * const Assert_fields[]={ - "test", - "msg", -}; -static const char * const Import_fields[]={ - "names", -}; -static const char * const ImportFrom_fields[]={ - "module", - "names", - "level", -}; -static const char * const Global_fields[]={ - "names", -}; -static const char * const Nonlocal_fields[]={ - "names", -}; -static const char * const Expr_fields[]={ - "value", -}; -static const char * const expr_attributes[] = { - "lineno", - "col_offset", - "end_lineno", - "end_col_offset", -}; -static PyObject* ast2obj_expr(struct ast_state *state, void*); -static const char * const BoolOp_fields[]={ - "op", - "values", -}; -static const char * const NamedExpr_fields[]={ - "target", - "value", -}; -static const char * const BinOp_fields[]={ - "left", - "op", - "right", -}; -static const char * const UnaryOp_fields[]={ - "op", - "operand", -}; -static const char * const Lambda_fields[]={ - "args", - "body", -}; -static const char * const IfExp_fields[]={ - "test", - "body", - "orelse", -}; -static const char * const Dict_fields[]={ - "keys", - "values", -}; -static const char * const Set_fields[]={ - "elts", -}; -static const char * const ListComp_fields[]={ - "elt", - "generators", -}; -static const char * const SetComp_fields[]={ - "elt", - "generators", -}; -static const char * const DictComp_fields[]={ - "key", - "value", - "generators", -}; -static const char * const GeneratorExp_fields[]={ - "elt", - "generators", -}; -static const char * const Await_fields[]={ - "value", -}; -static const char * const Yield_fields[]={ - "value", -}; -static const char * const YieldFrom_fields[]={ - "value", -}; -static const char * const Compare_fields[]={ - "left", - "ops", - "comparators", -}; -static const char * const Call_fields[]={ - "func", - "args", - "keywords", -}; -static const char * const FormattedValue_fields[]={ - "value", - "conversion", - "format_spec", -}; -static const char * const JoinedStr_fields[]={ - "values", -}; -static const char * const Constant_fields[]={ - "value", - "kind", -}; -static const char * const Attribute_fields[]={ - "value", - "attr", - "ctx", -}; -static const char * const Subscript_fields[]={ - "value", - "slice", - "ctx", -}; -static const char * const Starred_fields[]={ - "value", - "ctx", -}; -static const char * const Name_fields[]={ - "id", - "ctx", -}; -static const char * const List_fields[]={ - "elts", - "ctx", -}; -static const char * const Tuple_fields[]={ - "elts", - "ctx", -}; -static const char * const Slice_fields[]={ - "lower", - "upper", - "step", -}; -static PyObject* ast2obj_expr_context(struct ast_state *state, expr_context_ty); -static PyObject* ast2obj_boolop(struct ast_state *state, boolop_ty); -static PyObject* ast2obj_operator(struct ast_state *state, operator_ty); -static PyObject* ast2obj_unaryop(struct ast_state *state, unaryop_ty); -static PyObject* ast2obj_cmpop(struct ast_state *state, cmpop_ty); -static PyObject* ast2obj_comprehension(struct ast_state *state, void*); -static const char * const comprehension_fields[]={ - "target", - "iter", - "ifs", - "is_async", -}; -static const char * const excepthandler_attributes[] = { - "lineno", - "col_offset", - "end_lineno", - "end_col_offset", -}; -static PyObject* ast2obj_excepthandler(struct ast_state *state, void*); -static const char * const ExceptHandler_fields[]={ - "type", - "name", - "body", -}; -static PyObject* ast2obj_arguments(struct ast_state *state, void*); -static const char * const arguments_fields[]={ - "posonlyargs", - "args", - "vararg", - "kwonlyargs", - "kw_defaults", - "kwarg", - "defaults", -}; -static PyObject* ast2obj_arg(struct ast_state *state, void*); -static const char * const arg_attributes[] = { - "lineno", - "col_offset", - "end_lineno", - "end_col_offset", -}; -static const char * const arg_fields[]={ - "arg", - "annotation", - "type_comment", -}; -static PyObject* ast2obj_keyword(struct ast_state *state, void*); -static const char * const keyword_attributes[] = { - "lineno", - "col_offset", - "end_lineno", - "end_col_offset", -}; -static const char * const keyword_fields[]={ - "arg", - "value", -}; -static PyObject* ast2obj_alias(struct ast_state *state, void*); -static const char * const alias_attributes[] = { - "lineno", - "col_offset", - "end_lineno", - "end_col_offset", -}; -static const char * const alias_fields[]={ - "name", - "asname", -}; -static PyObject* ast2obj_withitem(struct ast_state *state, void*); -static const char * const withitem_fields[]={ - "context_expr", - "optional_vars", -}; -static PyObject* ast2obj_match_case(struct ast_state *state, void*); -static const char * const match_case_fields[]={ - "pattern", - "guard", - "body", -}; -static const char * const pattern_attributes[] = { - "lineno", - "col_offset", - "end_lineno", - "end_col_offset", -}; -static PyObject* ast2obj_pattern(struct ast_state *state, void*); -static const char * const MatchValue_fields[]={ - "value", -}; -static const char * const MatchSingleton_fields[]={ - "value", -}; -static const char * const MatchSequence_fields[]={ - "patterns", -}; -static const char * const MatchMapping_fields[]={ - "keys", - "patterns", - "rest", -}; -static const char * const MatchClass_fields[]={ - "cls", - "patterns", - "kwd_attrs", - "kwd_patterns", -}; -static const char * const MatchStar_fields[]={ - "name", -}; -static const char * const MatchAs_fields[]={ - "pattern", - "name", -}; -static const char * const MatchOr_fields[]={ - "patterns", -}; -static PyObject* ast2obj_type_ignore(struct ast_state *state, void*); -static const char * const TypeIgnore_fields[]={ - "lineno", - "tag", -}; - - - -typedef struct { - PyObject_HEAD - PyObject *dict; -} AST_object; - -static void -ast_dealloc(AST_object *self) -{ - /* bpo-31095: UnTrack is needed before calling any callbacks */ - PyTypeObject *tp = Py_TYPE(self); - PyObject_GC_UnTrack(self); - Py_CLEAR(self->dict); - freefunc free_func = PyType_GetSlot(tp, Py_tp_free); - assert(free_func != NULL); - free_func(self); - Py_DECREF(tp); -} - -static int -ast_traverse(AST_object *self, visitproc visit, void *arg) -{ - Py_VISIT(Py_TYPE(self)); - Py_VISIT(self->dict); - return 0; -} - -static int -ast_clear(AST_object *self) -{ - Py_CLEAR(self->dict); - return 0; -} - -static int -ast_type_init(PyObject *self, PyObject *args, PyObject *kw) -{ - struct ast_state *state = get_ast_state(); - if (state == NULL) { - return -1; - } - - Py_ssize_t i, numfields = 0; - int res = -1; - PyObject *key, *value, *fields; - if (_PyObject_LookupAttr((PyObject*)Py_TYPE(self), state->_fields, &fields) < 0) { - goto cleanup; - } - if (fields) { - numfields = PySequence_Size(fields); - if (numfields == -1) { - goto cleanup; - } - } - - res = 0; /* if no error occurs, this stays 0 to the end */ - if (numfields < PyTuple_GET_SIZE(args)) { - PyErr_Format(PyExc_TypeError, "%.400s constructor takes at most " - "%zd positional argument%s", - _PyType_Name(Py_TYPE(self)), - numfields, numfields == 1 ? "" : "s"); - res = -1; - goto cleanup; - } - for (i = 0; i < PyTuple_GET_SIZE(args); i++) { - /* cannot be reached when fields is NULL */ - PyObject *name = PySequence_GetItem(fields, i); - if (!name) { - res = -1; - goto cleanup; - } - res = PyObject_SetAttr(self, name, PyTuple_GET_ITEM(args, i)); - Py_DECREF(name); - if (res < 0) { - goto cleanup; - } - } - if (kw) { - i = 0; /* needed by PyDict_Next */ - while (PyDict_Next(kw, &i, &key, &value)) { - int contains = PySequence_Contains(fields, key); - if (contains == -1) { - res = -1; - goto cleanup; - } else if (contains == 1) { - Py_ssize_t p = PySequence_Index(fields, key); - if (p == -1) { - res = -1; - goto cleanup; - } - if (p < PyTuple_GET_SIZE(args)) { - PyErr_Format(PyExc_TypeError, - "%.400s got multiple values for argument '%U'", - Py_TYPE(self)->tp_name, key); - res = -1; - goto cleanup; - } - } - res = PyObject_SetAttr(self, key, value); - if (res < 0) { - goto cleanup; - } - } - } - cleanup: - Py_XDECREF(fields); - return res; -} - -/* Pickling support */ -static PyObject * -ast_type_reduce(PyObject *self, PyObject *unused) -{ - struct ast_state *state = get_ast_state(); - if (state == NULL) { - return NULL; - } - - PyObject *dict; - if (_PyObject_LookupAttr(self, state->__dict__, &dict) < 0) { - return NULL; - } - if (dict) { - return Py_BuildValue("O()N", Py_TYPE(self), dict); - } - return Py_BuildValue("O()", Py_TYPE(self)); -} - -static PyMemberDef ast_type_members[] = { - {"__dictoffset__", T_PYSSIZET, offsetof(AST_object, dict), READONLY}, - {NULL} /* Sentinel */ -}; - -static PyMethodDef ast_type_methods[] = { - {"__reduce__", ast_type_reduce, METH_NOARGS, NULL}, - {NULL} -}; - -static PyGetSetDef ast_type_getsets[] = { - {"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict}, - {NULL} -}; - -static PyType_Slot AST_type_slots[] = { - {Py_tp_dealloc, ast_dealloc}, - {Py_tp_getattro, PyObject_GenericGetAttr}, - {Py_tp_setattro, PyObject_GenericSetAttr}, - {Py_tp_traverse, ast_traverse}, - {Py_tp_clear, ast_clear}, - {Py_tp_members, ast_type_members}, - {Py_tp_methods, ast_type_methods}, - {Py_tp_getset, ast_type_getsets}, - {Py_tp_init, ast_type_init}, - {Py_tp_alloc, PyType_GenericAlloc}, - {Py_tp_new, PyType_GenericNew}, - {Py_tp_free, PyObject_GC_Del}, - {0, 0}, -}; - -static PyType_Spec AST_type_spec = { - "ast.AST", - sizeof(AST_object), - 0, - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, - AST_type_slots -}; - -static PyObject * -make_type(struct ast_state *state, const char *type, PyObject* base, - const char* const* fields, int num_fields, const char *doc) -{ - PyObject *fnames, *result; - int i; - fnames = PyTuple_New(num_fields); - if (!fnames) return NULL; - for (i = 0; i < num_fields; i++) { - PyObject *field = PyUnicode_InternFromString(fields[i]); - if (!field) { - Py_DECREF(fnames); - return NULL; - } - PyTuple_SET_ITEM(fnames, i, field); - } - result = PyObject_CallFunction((PyObject*)&PyType_Type, "s(O){OOOOOOOs}", - type, base, - state->_fields, fnames, - state->__match_args__, fnames, - state->__module__, - state->ast, - state->__doc__, doc); - Py_DECREF(fnames); - return result; -} - -static int -add_attributes(struct ast_state *state, PyObject *type, const char * const *attrs, int num_fields) -{ - int i, result; - PyObject *s, *l = PyTuple_New(num_fields); - if (!l) - return 0; - for (i = 0; i < num_fields; i++) { - s = PyUnicode_InternFromString(attrs[i]); - if (!s) { - Py_DECREF(l); - return 0; - } - PyTuple_SET_ITEM(l, i, s); - } - result = PyObject_SetAttr(type, state->_attributes, l) >= 0; - Py_DECREF(l); - return result; -} - -/* Conversion AST -> Python */ - -static PyObject* ast2obj_list(struct ast_state *state, asdl_seq *seq, PyObject* (*func)(struct ast_state *state, void*)) -{ - Py_ssize_t i, n = asdl_seq_LEN(seq); - PyObject *result = PyList_New(n); - PyObject *value; - if (!result) - return NULL; - for (i = 0; i < n; i++) { - value = func(state, asdl_seq_GET_UNTYPED(seq, i)); - if (!value) { - Py_DECREF(result); - return NULL; - } - PyList_SET_ITEM(result, i, value); - } - return result; -} - -static PyObject* ast2obj_object(struct ast_state *Py_UNUSED(state), void *o) -{ - if (!o) - o = Py_None; - Py_INCREF((PyObject*)o); - return (PyObject*)o; -} -#define ast2obj_constant ast2obj_object -#define ast2obj_identifier ast2obj_object -#define ast2obj_string ast2obj_object - -static PyObject* ast2obj_int(struct ast_state *Py_UNUSED(state), long b) -{ - return PyLong_FromLong(b); -} - -/* Conversion Python -> AST */ - -static int obj2ast_object(struct ast_state *Py_UNUSED(state), PyObject* obj, PyObject** out, PyArena* arena) -{ - if (obj == Py_None) - obj = NULL; - if (obj) { - if (_PyArena_AddPyObject(arena, obj) < 0) { - *out = NULL; - return -1; - } - Py_INCREF(obj); - } - *out = obj; - return 0; -} - -static int obj2ast_constant(struct ast_state *Py_UNUSED(state), PyObject* obj, PyObject** out, PyArena* arena) -{ - if (_PyArena_AddPyObject(arena, obj) < 0) { - *out = NULL; - return -1; - } - Py_INCREF(obj); - *out = obj; - return 0; -} - -static int obj2ast_identifier(struct ast_state *state, PyObject* obj, PyObject** out, PyArena* arena) -{ - if (!PyUnicode_CheckExact(obj) && obj != Py_None) { - PyErr_SetString(PyExc_TypeError, "AST identifier must be of type str"); - return 1; - } - return obj2ast_object(state, obj, out, arena); -} - -static int obj2ast_string(struct ast_state *state, PyObject* obj, PyObject** out, PyArena* arena) -{ - if (!PyUnicode_CheckExact(obj) && !PyBytes_CheckExact(obj)) { - PyErr_SetString(PyExc_TypeError, "AST string must be of type str"); - return 1; - } - return obj2ast_object(state, obj, out, arena); -} - -static int obj2ast_int(struct ast_state* Py_UNUSED(state), PyObject* obj, int* out, PyArena* arena) -{ - int i; - if (!PyLong_Check(obj)) { - PyErr_Format(PyExc_ValueError, "invalid integer value: %R", obj); - return 1; - } - - i = _PyLong_AsInt(obj); - if (i == -1 && PyErr_Occurred()) - return 1; - *out = i; - return 0; -} - -static int add_ast_fields(struct ast_state *state) -{ - PyObject *empty_tuple; - empty_tuple = PyTuple_New(0); - if (!empty_tuple || - PyObject_SetAttrString(state->AST_type, "_fields", empty_tuple) < 0 || - PyObject_SetAttrString(state->AST_type, "__match_args__", empty_tuple) < 0 || - PyObject_SetAttrString(state->AST_type, "_attributes", empty_tuple) < 0) { - Py_XDECREF(empty_tuple); - return -1; - } - Py_DECREF(empty_tuple); - return 0; -} - - - -static int -init_types(struct ast_state *state) -{ - // init_types() must not be called after _PyAST_Fini() - // has been called - assert(state->initialized >= 0); - - if (state->initialized) { - return 1; - } - if (init_identifiers(state) < 0) { - return 0; - } - state->AST_type = PyType_FromSpec(&AST_type_spec); - if (!state->AST_type) { - return 0; - } - if (add_ast_fields(state) < 0) { - return 0; - } - state->mod_type = make_type(state, "mod", state->AST_type, NULL, 0, - "mod = Module(stmt* body, type_ignore* type_ignores)\n" - " | Interactive(stmt* body)\n" - " | Expression(expr body)\n" - " | FunctionType(expr* argtypes, expr returns)"); - if (!state->mod_type) return 0; - if (!add_attributes(state, state->mod_type, NULL, 0)) return 0; - state->Module_type = make_type(state, "Module", state->mod_type, - Module_fields, 2, - "Module(stmt* body, type_ignore* type_ignores)"); - if (!state->Module_type) return 0; - state->Interactive_type = make_type(state, "Interactive", state->mod_type, - Interactive_fields, 1, - "Interactive(stmt* body)"); - if (!state->Interactive_type) return 0; - state->Expression_type = make_type(state, "Expression", state->mod_type, - Expression_fields, 1, - "Expression(expr body)"); - if (!state->Expression_type) return 0; - state->FunctionType_type = make_type(state, "FunctionType", - state->mod_type, FunctionType_fields, - 2, - "FunctionType(expr* argtypes, expr returns)"); - if (!state->FunctionType_type) return 0; - state->stmt_type = make_type(state, "stmt", state->AST_type, NULL, 0, - "stmt = FunctionDef(identifier name, arguments args, stmt* body, expr* decorator_list, expr? returns, string? type_comment)\n" - " | AsyncFunctionDef(identifier name, arguments args, stmt* body, expr* decorator_list, expr? returns, string? type_comment)\n" - " | ClassDef(identifier name, expr* bases, keyword* keywords, stmt* body, expr* decorator_list)\n" - " | Return(expr? value)\n" - " | Delete(expr* targets)\n" - " | Assign(expr* targets, expr value, string? type_comment)\n" - " | AugAssign(expr target, operator op, expr value)\n" - " | AnnAssign(expr target, expr annotation, expr? value, int simple)\n" - " | For(expr target, expr iter, stmt* body, stmt* orelse, string? type_comment)\n" - " | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse, string? type_comment)\n" - " | While(expr test, stmt* body, stmt* orelse)\n" - " | If(expr test, stmt* body, stmt* orelse)\n" - " | With(withitem* items, stmt* body, string? type_comment)\n" - " | AsyncWith(withitem* items, stmt* body, string? type_comment)\n" - " | Match(expr subject, match_case* cases)\n" - " | Raise(expr? exc, expr? cause)\n" - " | Try(stmt* body, excepthandler* handlers, stmt* orelse, stmt* finalbody)\n" - " | Assert(expr test, expr? msg)\n" - " | Import(alias* names)\n" - " | ImportFrom(identifier? module, alias* names, int? level)\n" - " | Global(identifier* names)\n" - " | Nonlocal(identifier* names)\n" - " | Expr(expr value)\n" - " | Pass\n" - " | Break\n" - " | Continue"); - if (!state->stmt_type) return 0; - if (!add_attributes(state, state->stmt_type, stmt_attributes, 4)) return 0; - if (PyObject_SetAttr(state->stmt_type, state->end_lineno, Py_None) == -1) - return 0; - if (PyObject_SetAttr(state->stmt_type, state->end_col_offset, Py_None) == - -1) - return 0; - state->FunctionDef_type = make_type(state, "FunctionDef", state->stmt_type, - FunctionDef_fields, 6, - "FunctionDef(identifier name, arguments args, stmt* body, expr* decorator_list, expr? returns, string? type_comment)"); - if (!state->FunctionDef_type) return 0; - if (PyObject_SetAttr(state->FunctionDef_type, state->returns, Py_None) == - -1) - return 0; - if (PyObject_SetAttr(state->FunctionDef_type, state->type_comment, Py_None) - == -1) - return 0; - state->AsyncFunctionDef_type = make_type(state, "AsyncFunctionDef", - state->stmt_type, - AsyncFunctionDef_fields, 6, - "AsyncFunctionDef(identifier name, arguments args, stmt* body, expr* decorator_list, expr? returns, string? type_comment)"); - if (!state->AsyncFunctionDef_type) return 0; - if (PyObject_SetAttr(state->AsyncFunctionDef_type, state->returns, Py_None) - == -1) - return 0; - if (PyObject_SetAttr(state->AsyncFunctionDef_type, state->type_comment, - Py_None) == -1) - return 0; - state->ClassDef_type = make_type(state, "ClassDef", state->stmt_type, - ClassDef_fields, 5, - "ClassDef(identifier name, expr* bases, keyword* keywords, stmt* body, expr* decorator_list)"); - if (!state->ClassDef_type) return 0; - state->Return_type = make_type(state, "Return", state->stmt_type, - Return_fields, 1, - "Return(expr? value)"); - if (!state->Return_type) return 0; - if (PyObject_SetAttr(state->Return_type, state->value, Py_None) == -1) - return 0; - state->Delete_type = make_type(state, "Delete", state->stmt_type, - Delete_fields, 1, - "Delete(expr* targets)"); - if (!state->Delete_type) return 0; - state->Assign_type = make_type(state, "Assign", state->stmt_type, - Assign_fields, 3, - "Assign(expr* targets, expr value, string? type_comment)"); - if (!state->Assign_type) return 0; - if (PyObject_SetAttr(state->Assign_type, state->type_comment, Py_None) == - -1) - return 0; - state->AugAssign_type = make_type(state, "AugAssign", state->stmt_type, - AugAssign_fields, 3, - "AugAssign(expr target, operator op, expr value)"); - if (!state->AugAssign_type) return 0; - state->AnnAssign_type = make_type(state, "AnnAssign", state->stmt_type, - AnnAssign_fields, 4, - "AnnAssign(expr target, expr annotation, expr? value, int simple)"); - if (!state->AnnAssign_type) return 0; - if (PyObject_SetAttr(state->AnnAssign_type, state->value, Py_None) == -1) - return 0; - state->For_type = make_type(state, "For", state->stmt_type, For_fields, 5, - "For(expr target, expr iter, stmt* body, stmt* orelse, string? type_comment)"); - if (!state->For_type) return 0; - if (PyObject_SetAttr(state->For_type, state->type_comment, Py_None) == -1) - return 0; - state->AsyncFor_type = make_type(state, "AsyncFor", state->stmt_type, - AsyncFor_fields, 5, - "AsyncFor(expr target, expr iter, stmt* body, stmt* orelse, string? type_comment)"); - if (!state->AsyncFor_type) return 0; - if (PyObject_SetAttr(state->AsyncFor_type, state->type_comment, Py_None) == - -1) - return 0; - state->While_type = make_type(state, "While", state->stmt_type, - While_fields, 3, - "While(expr test, stmt* body, stmt* orelse)"); - if (!state->While_type) return 0; - state->If_type = make_type(state, "If", state->stmt_type, If_fields, 3, - "If(expr test, stmt* body, stmt* orelse)"); - if (!state->If_type) return 0; - state->With_type = make_type(state, "With", state->stmt_type, With_fields, - 3, - "With(withitem* items, stmt* body, string? type_comment)"); - if (!state->With_type) return 0; - if (PyObject_SetAttr(state->With_type, state->type_comment, Py_None) == -1) - return 0; - state->AsyncWith_type = make_type(state, "AsyncWith", state->stmt_type, - AsyncWith_fields, 3, - "AsyncWith(withitem* items, stmt* body, string? type_comment)"); - if (!state->AsyncWith_type) return 0; - if (PyObject_SetAttr(state->AsyncWith_type, state->type_comment, Py_None) - == -1) - return 0; - state->Match_type = make_type(state, "Match", state->stmt_type, - Match_fields, 2, - "Match(expr subject, match_case* cases)"); - if (!state->Match_type) return 0; - state->Raise_type = make_type(state, "Raise", state->stmt_type, - Raise_fields, 2, - "Raise(expr? exc, expr? cause)"); - if (!state->Raise_type) return 0; - if (PyObject_SetAttr(state->Raise_type, state->exc, Py_None) == -1) - return 0; - if (PyObject_SetAttr(state->Raise_type, state->cause, Py_None) == -1) - return 0; - state->Try_type = make_type(state, "Try", state->stmt_type, Try_fields, 4, - "Try(stmt* body, excepthandler* handlers, stmt* orelse, stmt* finalbody)"); - if (!state->Try_type) return 0; - state->Assert_type = make_type(state, "Assert", state->stmt_type, - Assert_fields, 2, - "Assert(expr test, expr? msg)"); - if (!state->Assert_type) return 0; - if (PyObject_SetAttr(state->Assert_type, state->msg, Py_None) == -1) - return 0; - state->Import_type = make_type(state, "Import", state->stmt_type, - Import_fields, 1, - "Import(alias* names)"); - if (!state->Import_type) return 0; - state->ImportFrom_type = make_type(state, "ImportFrom", state->stmt_type, - ImportFrom_fields, 3, - "ImportFrom(identifier? module, alias* names, int? level)"); - if (!state->ImportFrom_type) return 0; - if (PyObject_SetAttr(state->ImportFrom_type, state->module, Py_None) == -1) - return 0; - if (PyObject_SetAttr(state->ImportFrom_type, state->level, Py_None) == -1) - return 0; - state->Global_type = make_type(state, "Global", state->stmt_type, - Global_fields, 1, - "Global(identifier* names)"); - if (!state->Global_type) return 0; - state->Nonlocal_type = make_type(state, "Nonlocal", state->stmt_type, - Nonlocal_fields, 1, - "Nonlocal(identifier* names)"); - if (!state->Nonlocal_type) return 0; - state->Expr_type = make_type(state, "Expr", state->stmt_type, Expr_fields, - 1, - "Expr(expr value)"); - if (!state->Expr_type) return 0; - state->Pass_type = make_type(state, "Pass", state->stmt_type, NULL, 0, - "Pass"); - if (!state->Pass_type) return 0; - state->Break_type = make_type(state, "Break", state->stmt_type, NULL, 0, - "Break"); - if (!state->Break_type) return 0; - state->Continue_type = make_type(state, "Continue", state->stmt_type, NULL, - 0, - "Continue"); - if (!state->Continue_type) return 0; - state->expr_type = make_type(state, "expr", state->AST_type, NULL, 0, - "expr = BoolOp(boolop op, expr* values)\n" - " | NamedExpr(expr target, expr value)\n" - " | BinOp(expr left, operator op, expr right)\n" - " | UnaryOp(unaryop op, expr operand)\n" - " | Lambda(arguments args, expr body)\n" - " | IfExp(expr test, expr body, expr orelse)\n" - " | Dict(expr* keys, expr* values)\n" - " | Set(expr* elts)\n" - " | ListComp(expr elt, comprehension* generators)\n" - " | SetComp(expr elt, comprehension* generators)\n" - " | DictComp(expr key, expr value, comprehension* generators)\n" - " | GeneratorExp(expr elt, comprehension* generators)\n" - " | Await(expr value)\n" - " | Yield(expr? value)\n" - " | YieldFrom(expr value)\n" - " | Compare(expr left, cmpop* ops, expr* comparators)\n" - " | Call(expr func, expr* args, keyword* keywords)\n" - " | FormattedValue(expr value, int conversion, expr? format_spec)\n" - " | JoinedStr(expr* values)\n" - " | Constant(constant value, string? kind)\n" - " | Attribute(expr value, identifier attr, expr_context ctx)\n" - " | Subscript(expr value, expr slice, expr_context ctx)\n" - " | Starred(expr value, expr_context ctx)\n" - " | Name(identifier id, expr_context ctx)\n" - " | List(expr* elts, expr_context ctx)\n" - " | Tuple(expr* elts, expr_context ctx)\n" - " | Slice(expr? lower, expr? upper, expr? step)"); - if (!state->expr_type) return 0; - if (!add_attributes(state, state->expr_type, expr_attributes, 4)) return 0; - if (PyObject_SetAttr(state->expr_type, state->end_lineno, Py_None) == -1) - return 0; - if (PyObject_SetAttr(state->expr_type, state->end_col_offset, Py_None) == - -1) - return 0; - state->BoolOp_type = make_type(state, "BoolOp", state->expr_type, - BoolOp_fields, 2, - "BoolOp(boolop op, expr* values)"); - if (!state->BoolOp_type) return 0; - state->NamedExpr_type = make_type(state, "NamedExpr", state->expr_type, - NamedExpr_fields, 2, - "NamedExpr(expr target, expr value)"); - if (!state->NamedExpr_type) return 0; - state->BinOp_type = make_type(state, "BinOp", state->expr_type, - BinOp_fields, 3, - "BinOp(expr left, operator op, expr right)"); - if (!state->BinOp_type) return 0; - state->UnaryOp_type = make_type(state, "UnaryOp", state->expr_type, - UnaryOp_fields, 2, - "UnaryOp(unaryop op, expr operand)"); - if (!state->UnaryOp_type) return 0; - state->Lambda_type = make_type(state, "Lambda", state->expr_type, - Lambda_fields, 2, - "Lambda(arguments args, expr body)"); - if (!state->Lambda_type) return 0; - state->IfExp_type = make_type(state, "IfExp", state->expr_type, - IfExp_fields, 3, - "IfExp(expr test, expr body, expr orelse)"); - if (!state->IfExp_type) return 0; - state->Dict_type = make_type(state, "Dict", state->expr_type, Dict_fields, - 2, - "Dict(expr* keys, expr* values)"); - if (!state->Dict_type) return 0; - state->Set_type = make_type(state, "Set", state->expr_type, Set_fields, 1, - "Set(expr* elts)"); - if (!state->Set_type) return 0; - state->ListComp_type = make_type(state, "ListComp", state->expr_type, - ListComp_fields, 2, - "ListComp(expr elt, comprehension* generators)"); - if (!state->ListComp_type) return 0; - state->SetComp_type = make_type(state, "SetComp", state->expr_type, - SetComp_fields, 2, - "SetComp(expr elt, comprehension* generators)"); - if (!state->SetComp_type) return 0; - state->DictComp_type = make_type(state, "DictComp", state->expr_type, - DictComp_fields, 3, - "DictComp(expr key, expr value, comprehension* generators)"); - if (!state->DictComp_type) return 0; - state->GeneratorExp_type = make_type(state, "GeneratorExp", - state->expr_type, GeneratorExp_fields, - 2, - "GeneratorExp(expr elt, comprehension* generators)"); - if (!state->GeneratorExp_type) return 0; - state->Await_type = make_type(state, "Await", state->expr_type, - Await_fields, 1, - "Await(expr value)"); - if (!state->Await_type) return 0; - state->Yield_type = make_type(state, "Yield", state->expr_type, - Yield_fields, 1, - "Yield(expr? value)"); - if (!state->Yield_type) return 0; - if (PyObject_SetAttr(state->Yield_type, state->value, Py_None) == -1) - return 0; - state->YieldFrom_type = make_type(state, "YieldFrom", state->expr_type, - YieldFrom_fields, 1, - "YieldFrom(expr value)"); - if (!state->YieldFrom_type) return 0; - state->Compare_type = make_type(state, "Compare", state->expr_type, - Compare_fields, 3, - "Compare(expr left, cmpop* ops, expr* comparators)"); - if (!state->Compare_type) return 0; - state->Call_type = make_type(state, "Call", state->expr_type, Call_fields, - 3, - "Call(expr func, expr* args, keyword* keywords)"); - if (!state->Call_type) return 0; - state->FormattedValue_type = make_type(state, "FormattedValue", - state->expr_type, - FormattedValue_fields, 3, - "FormattedValue(expr value, int conversion, expr? format_spec)"); - if (!state->FormattedValue_type) return 0; - if (PyObject_SetAttr(state->FormattedValue_type, state->format_spec, - Py_None) == -1) - return 0; - state->JoinedStr_type = make_type(state, "JoinedStr", state->expr_type, - JoinedStr_fields, 1, - "JoinedStr(expr* values)"); - if (!state->JoinedStr_type) return 0; - state->Constant_type = make_type(state, "Constant", state->expr_type, - Constant_fields, 2, - "Constant(constant value, string? kind)"); - if (!state->Constant_type) return 0; - if (PyObject_SetAttr(state->Constant_type, state->kind, Py_None) == -1) - return 0; - state->Attribute_type = make_type(state, "Attribute", state->expr_type, - Attribute_fields, 3, - "Attribute(expr value, identifier attr, expr_context ctx)"); - if (!state->Attribute_type) return 0; - state->Subscript_type = make_type(state, "Subscript", state->expr_type, - Subscript_fields, 3, - "Subscript(expr value, expr slice, expr_context ctx)"); - if (!state->Subscript_type) return 0; - state->Starred_type = make_type(state, "Starred", state->expr_type, - Starred_fields, 2, - "Starred(expr value, expr_context ctx)"); - if (!state->Starred_type) return 0; - state->Name_type = make_type(state, "Name", state->expr_type, Name_fields, - 2, - "Name(identifier id, expr_context ctx)"); - if (!state->Name_type) return 0; - state->List_type = make_type(state, "List", state->expr_type, List_fields, - 2, - "List(expr* elts, expr_context ctx)"); - if (!state->List_type) return 0; - state->Tuple_type = make_type(state, "Tuple", state->expr_type, - Tuple_fields, 2, - "Tuple(expr* elts, expr_context ctx)"); - if (!state->Tuple_type) return 0; - state->Slice_type = make_type(state, "Slice", state->expr_type, - Slice_fields, 3, - "Slice(expr? lower, expr? upper, expr? step)"); - if (!state->Slice_type) return 0; - if (PyObject_SetAttr(state->Slice_type, state->lower, Py_None) == -1) - return 0; - if (PyObject_SetAttr(state->Slice_type, state->upper, Py_None) == -1) - return 0; - if (PyObject_SetAttr(state->Slice_type, state->step, Py_None) == -1) - return 0; - state->expr_context_type = make_type(state, "expr_context", - state->AST_type, NULL, 0, - "expr_context = Load | Store | Del"); - if (!state->expr_context_type) return 0; - if (!add_attributes(state, state->expr_context_type, NULL, 0)) return 0; - state->Load_type = make_type(state, "Load", state->expr_context_type, NULL, - 0, - "Load"); - if (!state->Load_type) return 0; - state->Load_singleton = PyType_GenericNew((PyTypeObject *)state->Load_type, - NULL, NULL); - if (!state->Load_singleton) return 0; - state->Store_type = make_type(state, "Store", state->expr_context_type, - NULL, 0, - "Store"); - if (!state->Store_type) return 0; - state->Store_singleton = PyType_GenericNew((PyTypeObject - *)state->Store_type, NULL, NULL); - if (!state->Store_singleton) return 0; - state->Del_type = make_type(state, "Del", state->expr_context_type, NULL, 0, - "Del"); - if (!state->Del_type) return 0; - state->Del_singleton = PyType_GenericNew((PyTypeObject *)state->Del_type, - NULL, NULL); - if (!state->Del_singleton) return 0; - state->boolop_type = make_type(state, "boolop", state->AST_type, NULL, 0, - "boolop = And | Or"); - if (!state->boolop_type) return 0; - if (!add_attributes(state, state->boolop_type, NULL, 0)) return 0; - state->And_type = make_type(state, "And", state->boolop_type, NULL, 0, - "And"); - if (!state->And_type) return 0; - state->And_singleton = PyType_GenericNew((PyTypeObject *)state->And_type, - NULL, NULL); - if (!state->And_singleton) return 0; - state->Or_type = make_type(state, "Or", state->boolop_type, NULL, 0, - "Or"); - if (!state->Or_type) return 0; - state->Or_singleton = PyType_GenericNew((PyTypeObject *)state->Or_type, - NULL, NULL); - if (!state->Or_singleton) return 0; - state->operator_type = make_type(state, "operator", state->AST_type, NULL, - 0, - "operator = Add | Sub | Mult | MatMult | Div | Mod | Pow | LShift | RShift | BitOr | BitXor | BitAnd | FloorDiv"); - if (!state->operator_type) return 0; - if (!add_attributes(state, state->operator_type, NULL, 0)) return 0; - state->Add_type = make_type(state, "Add", state->operator_type, NULL, 0, - "Add"); - if (!state->Add_type) return 0; - state->Add_singleton = PyType_GenericNew((PyTypeObject *)state->Add_type, - NULL, NULL); - if (!state->Add_singleton) return 0; - state->Sub_type = make_type(state, "Sub", state->operator_type, NULL, 0, - "Sub"); - if (!state->Sub_type) return 0; - state->Sub_singleton = PyType_GenericNew((PyTypeObject *)state->Sub_type, - NULL, NULL); - if (!state->Sub_singleton) return 0; - state->Mult_type = make_type(state, "Mult", state->operator_type, NULL, 0, - "Mult"); - if (!state->Mult_type) return 0; - state->Mult_singleton = PyType_GenericNew((PyTypeObject *)state->Mult_type, - NULL, NULL); - if (!state->Mult_singleton) return 0; - state->MatMult_type = make_type(state, "MatMult", state->operator_type, - NULL, 0, - "MatMult"); - if (!state->MatMult_type) return 0; - state->MatMult_singleton = PyType_GenericNew((PyTypeObject - *)state->MatMult_type, NULL, - NULL); - if (!state->MatMult_singleton) return 0; - state->Div_type = make_type(state, "Div", state->operator_type, NULL, 0, - "Div"); - if (!state->Div_type) return 0; - state->Div_singleton = PyType_GenericNew((PyTypeObject *)state->Div_type, - NULL, NULL); - if (!state->Div_singleton) return 0; - state->Mod_type = make_type(state, "Mod", state->operator_type, NULL, 0, - "Mod"); - if (!state->Mod_type) return 0; - state->Mod_singleton = PyType_GenericNew((PyTypeObject *)state->Mod_type, - NULL, NULL); - if (!state->Mod_singleton) return 0; - state->Pow_type = make_type(state, "Pow", state->operator_type, NULL, 0, - "Pow"); - if (!state->Pow_type) return 0; - state->Pow_singleton = PyType_GenericNew((PyTypeObject *)state->Pow_type, - NULL, NULL); - if (!state->Pow_singleton) return 0; - state->LShift_type = make_type(state, "LShift", state->operator_type, NULL, - 0, - "LShift"); - if (!state->LShift_type) return 0; - state->LShift_singleton = PyType_GenericNew((PyTypeObject - *)state->LShift_type, NULL, - NULL); - if (!state->LShift_singleton) return 0; - state->RShift_type = make_type(state, "RShift", state->operator_type, NULL, - 0, - "RShift"); - if (!state->RShift_type) return 0; - state->RShift_singleton = PyType_GenericNew((PyTypeObject - *)state->RShift_type, NULL, - NULL); - if (!state->RShift_singleton) return 0; - state->BitOr_type = make_type(state, "BitOr", state->operator_type, NULL, 0, - "BitOr"); - if (!state->BitOr_type) return 0; - state->BitOr_singleton = PyType_GenericNew((PyTypeObject - *)state->BitOr_type, NULL, NULL); - if (!state->BitOr_singleton) return 0; - state->BitXor_type = make_type(state, "BitXor", state->operator_type, NULL, - 0, - "BitXor"); - if (!state->BitXor_type) return 0; - state->BitXor_singleton = PyType_GenericNew((PyTypeObject - *)state->BitXor_type, NULL, - NULL); - if (!state->BitXor_singleton) return 0; - state->BitAnd_type = make_type(state, "BitAnd", state->operator_type, NULL, - 0, - "BitAnd"); - if (!state->BitAnd_type) return 0; - state->BitAnd_singleton = PyType_GenericNew((PyTypeObject - *)state->BitAnd_type, NULL, - NULL); - if (!state->BitAnd_singleton) return 0; - state->FloorDiv_type = make_type(state, "FloorDiv", state->operator_type, - NULL, 0, - "FloorDiv"); - if (!state->FloorDiv_type) return 0; - state->FloorDiv_singleton = PyType_GenericNew((PyTypeObject - *)state->FloorDiv_type, NULL, - NULL); - if (!state->FloorDiv_singleton) return 0; - state->unaryop_type = make_type(state, "unaryop", state->AST_type, NULL, 0, - "unaryop = Invert | Not | UAdd | USub"); - if (!state->unaryop_type) return 0; - if (!add_attributes(state, state->unaryop_type, NULL, 0)) return 0; - state->Invert_type = make_type(state, "Invert", state->unaryop_type, NULL, - 0, - "Invert"); - if (!state->Invert_type) return 0; - state->Invert_singleton = PyType_GenericNew((PyTypeObject - *)state->Invert_type, NULL, - NULL); - if (!state->Invert_singleton) return 0; - state->Not_type = make_type(state, "Not", state->unaryop_type, NULL, 0, - "Not"); - if (!state->Not_type) return 0; - state->Not_singleton = PyType_GenericNew((PyTypeObject *)state->Not_type, - NULL, NULL); - if (!state->Not_singleton) return 0; - state->UAdd_type = make_type(state, "UAdd", state->unaryop_type, NULL, 0, - "UAdd"); - if (!state->UAdd_type) return 0; - state->UAdd_singleton = PyType_GenericNew((PyTypeObject *)state->UAdd_type, - NULL, NULL); - if (!state->UAdd_singleton) return 0; - state->USub_type = make_type(state, "USub", state->unaryop_type, NULL, 0, - "USub"); - if (!state->USub_type) return 0; - state->USub_singleton = PyType_GenericNew((PyTypeObject *)state->USub_type, - NULL, NULL); - if (!state->USub_singleton) return 0; - state->cmpop_type = make_type(state, "cmpop", state->AST_type, NULL, 0, - "cmpop = Eq | NotEq | Lt | LtE | Gt | GtE | Is | IsNot | In | NotIn"); - if (!state->cmpop_type) return 0; - if (!add_attributes(state, state->cmpop_type, NULL, 0)) return 0; - state->Eq_type = make_type(state, "Eq", state->cmpop_type, NULL, 0, - "Eq"); - if (!state->Eq_type) return 0; - state->Eq_singleton = PyType_GenericNew((PyTypeObject *)state->Eq_type, - NULL, NULL); - if (!state->Eq_singleton) return 0; - state->NotEq_type = make_type(state, "NotEq", state->cmpop_type, NULL, 0, - "NotEq"); - if (!state->NotEq_type) return 0; - state->NotEq_singleton = PyType_GenericNew((PyTypeObject - *)state->NotEq_type, NULL, NULL); - if (!state->NotEq_singleton) return 0; - state->Lt_type = make_type(state, "Lt", state->cmpop_type, NULL, 0, - "Lt"); - if (!state->Lt_type) return 0; - state->Lt_singleton = PyType_GenericNew((PyTypeObject *)state->Lt_type, - NULL, NULL); - if (!state->Lt_singleton) return 0; - state->LtE_type = make_type(state, "LtE", state->cmpop_type, NULL, 0, - "LtE"); - if (!state->LtE_type) return 0; - state->LtE_singleton = PyType_GenericNew((PyTypeObject *)state->LtE_type, - NULL, NULL); - if (!state->LtE_singleton) return 0; - state->Gt_type = make_type(state, "Gt", state->cmpop_type, NULL, 0, - "Gt"); - if (!state->Gt_type) return 0; - state->Gt_singleton = PyType_GenericNew((PyTypeObject *)state->Gt_type, - NULL, NULL); - if (!state->Gt_singleton) return 0; - state->GtE_type = make_type(state, "GtE", state->cmpop_type, NULL, 0, - "GtE"); - if (!state->GtE_type) return 0; - state->GtE_singleton = PyType_GenericNew((PyTypeObject *)state->GtE_type, - NULL, NULL); - if (!state->GtE_singleton) return 0; - state->Is_type = make_type(state, "Is", state->cmpop_type, NULL, 0, - "Is"); - if (!state->Is_type) return 0; - state->Is_singleton = PyType_GenericNew((PyTypeObject *)state->Is_type, - NULL, NULL); - if (!state->Is_singleton) return 0; - state->IsNot_type = make_type(state, "IsNot", state->cmpop_type, NULL, 0, - "IsNot"); - if (!state->IsNot_type) return 0; - state->IsNot_singleton = PyType_GenericNew((PyTypeObject - *)state->IsNot_type, NULL, NULL); - if (!state->IsNot_singleton) return 0; - state->In_type = make_type(state, "In", state->cmpop_type, NULL, 0, - "In"); - if (!state->In_type) return 0; - state->In_singleton = PyType_GenericNew((PyTypeObject *)state->In_type, - NULL, NULL); - if (!state->In_singleton) return 0; - state->NotIn_type = make_type(state, "NotIn", state->cmpop_type, NULL, 0, - "NotIn"); - if (!state->NotIn_type) return 0; - state->NotIn_singleton = PyType_GenericNew((PyTypeObject - *)state->NotIn_type, NULL, NULL); - if (!state->NotIn_singleton) return 0; - state->comprehension_type = make_type(state, "comprehension", - state->AST_type, - comprehension_fields, 4, - "comprehension(expr target, expr iter, expr* ifs, int is_async)"); - if (!state->comprehension_type) return 0; - if (!add_attributes(state, state->comprehension_type, NULL, 0)) return 0; - state->excepthandler_type = make_type(state, "excepthandler", - state->AST_type, NULL, 0, - "excepthandler = ExceptHandler(expr? type, identifier? name, stmt* body)"); - if (!state->excepthandler_type) return 0; - if (!add_attributes(state, state->excepthandler_type, - excepthandler_attributes, 4)) return 0; - if (PyObject_SetAttr(state->excepthandler_type, state->end_lineno, Py_None) - == -1) - return 0; - if (PyObject_SetAttr(state->excepthandler_type, state->end_col_offset, - Py_None) == -1) - return 0; - state->ExceptHandler_type = make_type(state, "ExceptHandler", - state->excepthandler_type, - ExceptHandler_fields, 3, - "ExceptHandler(expr? type, identifier? name, stmt* body)"); - if (!state->ExceptHandler_type) return 0; - if (PyObject_SetAttr(state->ExceptHandler_type, state->type, Py_None) == -1) - return 0; - if (PyObject_SetAttr(state->ExceptHandler_type, state->name, Py_None) == -1) - return 0; - state->arguments_type = make_type(state, "arguments", state->AST_type, - arguments_fields, 7, - "arguments(arg* posonlyargs, arg* args, arg? vararg, arg* kwonlyargs, expr* kw_defaults, arg? kwarg, expr* defaults)"); - if (!state->arguments_type) return 0; - if (!add_attributes(state, state->arguments_type, NULL, 0)) return 0; - if (PyObject_SetAttr(state->arguments_type, state->vararg, Py_None) == -1) - return 0; - if (PyObject_SetAttr(state->arguments_type, state->kwarg, Py_None) == -1) - return 0; - state->arg_type = make_type(state, "arg", state->AST_type, arg_fields, 3, - "arg(identifier arg, expr? annotation, string? type_comment)"); - if (!state->arg_type) return 0; - if (!add_attributes(state, state->arg_type, arg_attributes, 4)) return 0; - if (PyObject_SetAttr(state->arg_type, state->annotation, Py_None) == -1) - return 0; - if (PyObject_SetAttr(state->arg_type, state->type_comment, Py_None) == -1) - return 0; - if (PyObject_SetAttr(state->arg_type, state->end_lineno, Py_None) == -1) - return 0; - if (PyObject_SetAttr(state->arg_type, state->end_col_offset, Py_None) == -1) - return 0; - state->keyword_type = make_type(state, "keyword", state->AST_type, - keyword_fields, 2, - "keyword(identifier? arg, expr value)"); - if (!state->keyword_type) return 0; - if (!add_attributes(state, state->keyword_type, keyword_attributes, 4)) - return 0; - if (PyObject_SetAttr(state->keyword_type, state->arg, Py_None) == -1) - return 0; - if (PyObject_SetAttr(state->keyword_type, state->end_lineno, Py_None) == -1) - return 0; - if (PyObject_SetAttr(state->keyword_type, state->end_col_offset, Py_None) - == -1) - return 0; - state->alias_type = make_type(state, "alias", state->AST_type, - alias_fields, 2, - "alias(identifier name, identifier? asname)"); - if (!state->alias_type) return 0; - if (!add_attributes(state, state->alias_type, alias_attributes, 4)) return - 0; - if (PyObject_SetAttr(state->alias_type, state->asname, Py_None) == -1) - return 0; - if (PyObject_SetAttr(state->alias_type, state->end_lineno, Py_None) == -1) - return 0; - if (PyObject_SetAttr(state->alias_type, state->end_col_offset, Py_None) == - -1) - return 0; - state->withitem_type = make_type(state, "withitem", state->AST_type, - withitem_fields, 2, - "withitem(expr context_expr, expr? optional_vars)"); - if (!state->withitem_type) return 0; - if (!add_attributes(state, state->withitem_type, NULL, 0)) return 0; - if (PyObject_SetAttr(state->withitem_type, state->optional_vars, Py_None) - == -1) - return 0; - state->match_case_type = make_type(state, "match_case", state->AST_type, - match_case_fields, 3, - "match_case(pattern pattern, expr? guard, stmt* body)"); - if (!state->match_case_type) return 0; - if (!add_attributes(state, state->match_case_type, NULL, 0)) return 0; - if (PyObject_SetAttr(state->match_case_type, state->guard, Py_None) == -1) - return 0; - state->pattern_type = make_type(state, "pattern", state->AST_type, NULL, 0, - "pattern = MatchValue(expr value)\n" - " | MatchSingleton(constant value)\n" - " | MatchSequence(pattern* patterns)\n" - " | MatchMapping(expr* keys, pattern* patterns, identifier? rest)\n" - " | MatchClass(expr cls, pattern* patterns, identifier* kwd_attrs, pattern* kwd_patterns)\n" - " | MatchStar(identifier? name)\n" - " | MatchAs(pattern? pattern, identifier? name)\n" - " | MatchOr(pattern* patterns)"); - if (!state->pattern_type) return 0; - if (!add_attributes(state, state->pattern_type, pattern_attributes, 4)) - return 0; - state->MatchValue_type = make_type(state, "MatchValue", - state->pattern_type, MatchValue_fields, - 1, - "MatchValue(expr value)"); - if (!state->MatchValue_type) return 0; - state->MatchSingleton_type = make_type(state, "MatchSingleton", - state->pattern_type, - MatchSingleton_fields, 1, - "MatchSingleton(constant value)"); - if (!state->MatchSingleton_type) return 0; - state->MatchSequence_type = make_type(state, "MatchSequence", - state->pattern_type, - MatchSequence_fields, 1, - "MatchSequence(pattern* patterns)"); - if (!state->MatchSequence_type) return 0; - state->MatchMapping_type = make_type(state, "MatchMapping", - state->pattern_type, - MatchMapping_fields, 3, - "MatchMapping(expr* keys, pattern* patterns, identifier? rest)"); - if (!state->MatchMapping_type) return 0; - if (PyObject_SetAttr(state->MatchMapping_type, state->rest, Py_None) == -1) - return 0; - state->MatchClass_type = make_type(state, "MatchClass", - state->pattern_type, MatchClass_fields, - 4, - "MatchClass(expr cls, pattern* patterns, identifier* kwd_attrs, pattern* kwd_patterns)"); - if (!state->MatchClass_type) return 0; - state->MatchStar_type = make_type(state, "MatchStar", state->pattern_type, - MatchStar_fields, 1, - "MatchStar(identifier? name)"); - if (!state->MatchStar_type) return 0; - if (PyObject_SetAttr(state->MatchStar_type, state->name, Py_None) == -1) - return 0; - state->MatchAs_type = make_type(state, "MatchAs", state->pattern_type, - MatchAs_fields, 2, - "MatchAs(pattern? pattern, identifier? name)"); - if (!state->MatchAs_type) return 0; - if (PyObject_SetAttr(state->MatchAs_type, state->pattern, Py_None) == -1) - return 0; - if (PyObject_SetAttr(state->MatchAs_type, state->name, Py_None) == -1) - return 0; - state->MatchOr_type = make_type(state, "MatchOr", state->pattern_type, - MatchOr_fields, 1, - "MatchOr(pattern* patterns)"); - if (!state->MatchOr_type) return 0; - state->type_ignore_type = make_type(state, "type_ignore", state->AST_type, - NULL, 0, - "type_ignore = TypeIgnore(int lineno, string tag)"); - if (!state->type_ignore_type) return 0; - if (!add_attributes(state, state->type_ignore_type, NULL, 0)) return 0; - state->TypeIgnore_type = make_type(state, "TypeIgnore", - state->type_ignore_type, - TypeIgnore_fields, 2, - "TypeIgnore(int lineno, string tag)"); - if (!state->TypeIgnore_type) return 0; - - state->initialized = 1; - return 1; -} - -static int obj2ast_mod(struct ast_state *state, PyObject* obj, mod_ty* out, - PyArena* arena); -static int obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, - PyArena* arena); -static int obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, - PyArena* arena); -static int obj2ast_expr_context(struct ast_state *state, PyObject* obj, - expr_context_ty* out, PyArena* arena); -static int obj2ast_boolop(struct ast_state *state, PyObject* obj, boolop_ty* - out, PyArena* arena); -static int obj2ast_operator(struct ast_state *state, PyObject* obj, - operator_ty* out, PyArena* arena); -static int obj2ast_unaryop(struct ast_state *state, PyObject* obj, unaryop_ty* - out, PyArena* arena); -static int obj2ast_cmpop(struct ast_state *state, PyObject* obj, cmpop_ty* out, - PyArena* arena); -static int obj2ast_comprehension(struct ast_state *state, PyObject* obj, - comprehension_ty* out, PyArena* arena); -static int obj2ast_excepthandler(struct ast_state *state, PyObject* obj, - excepthandler_ty* out, PyArena* arena); -static int obj2ast_arguments(struct ast_state *state, PyObject* obj, - arguments_ty* out, PyArena* arena); -static int obj2ast_arg(struct ast_state *state, PyObject* obj, arg_ty* out, - PyArena* arena); -static int obj2ast_keyword(struct ast_state *state, PyObject* obj, keyword_ty* - out, PyArena* arena); -static int obj2ast_alias(struct ast_state *state, PyObject* obj, alias_ty* out, - PyArena* arena); -static int obj2ast_withitem(struct ast_state *state, PyObject* obj, - withitem_ty* out, PyArena* arena); -static int obj2ast_match_case(struct ast_state *state, PyObject* obj, - match_case_ty* out, PyArena* arena); -static int obj2ast_pattern(struct ast_state *state, PyObject* obj, pattern_ty* - out, PyArena* arena); -static int obj2ast_type_ignore(struct ast_state *state, PyObject* obj, - type_ignore_ty* out, PyArena* arena); - -mod_ty -_PyAST_Module(asdl_stmt_seq * body, asdl_type_ignore_seq * type_ignores, - PyArena *arena) -{ - mod_ty p; - p = (mod_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->kind = Module_kind; - p->v.Module.body = body; - p->v.Module.type_ignores = type_ignores; - return p; -} - -mod_ty -_PyAST_Interactive(asdl_stmt_seq * body, PyArena *arena) -{ - mod_ty p; - p = (mod_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->kind = Interactive_kind; - p->v.Interactive.body = body; - return p; -} - -mod_ty -_PyAST_Expression(expr_ty body, PyArena *arena) -{ - mod_ty p; - if (!body) { - PyErr_SetString(PyExc_ValueError, - "field 'body' is required for Expression"); - return NULL; - } - p = (mod_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->kind = Expression_kind; - p->v.Expression.body = body; - return p; -} - -mod_ty -_PyAST_FunctionType(asdl_expr_seq * argtypes, expr_ty returns, PyArena *arena) -{ - mod_ty p; - if (!returns) { - PyErr_SetString(PyExc_ValueError, - "field 'returns' is required for FunctionType"); - return NULL; - } - p = (mod_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->kind = FunctionType_kind; - p->v.FunctionType.argtypes = argtypes; - p->v.FunctionType.returns = returns; - return p; -} - -stmt_ty -_PyAST_FunctionDef(identifier name, arguments_ty args, asdl_stmt_seq * body, - asdl_expr_seq * decorator_list, expr_ty returns, string - type_comment, int lineno, int col_offset, int end_lineno, - int end_col_offset, PyArena *arena) -{ - stmt_ty p; - if (!name) { - PyErr_SetString(PyExc_ValueError, - "field 'name' is required for FunctionDef"); - return NULL; - } - if (!args) { - PyErr_SetString(PyExc_ValueError, - "field 'args' is required for FunctionDef"); - return NULL; - } - p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->kind = FunctionDef_kind; - p->v.FunctionDef.name = name; - p->v.FunctionDef.args = args; - p->v.FunctionDef.body = body; - p->v.FunctionDef.decorator_list = decorator_list; - p->v.FunctionDef.returns = returns; - p->v.FunctionDef.type_comment = type_comment; - p->lineno = lineno; - p->col_offset = col_offset; - p->end_lineno = end_lineno; - p->end_col_offset = end_col_offset; - return p; -} - -stmt_ty -_PyAST_AsyncFunctionDef(identifier name, arguments_ty args, asdl_stmt_seq * - body, asdl_expr_seq * decorator_list, expr_ty returns, - string type_comment, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena) -{ - stmt_ty p; - if (!name) { - PyErr_SetString(PyExc_ValueError, - "field 'name' is required for AsyncFunctionDef"); - return NULL; - } - if (!args) { - PyErr_SetString(PyExc_ValueError, - "field 'args' is required for AsyncFunctionDef"); - return NULL; - } - p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->kind = AsyncFunctionDef_kind; - p->v.AsyncFunctionDef.name = name; - p->v.AsyncFunctionDef.args = args; - p->v.AsyncFunctionDef.body = body; - p->v.AsyncFunctionDef.decorator_list = decorator_list; - p->v.AsyncFunctionDef.returns = returns; - p->v.AsyncFunctionDef.type_comment = type_comment; - p->lineno = lineno; - p->col_offset = col_offset; - p->end_lineno = end_lineno; - p->end_col_offset = end_col_offset; - return p; -} - -stmt_ty -_PyAST_ClassDef(identifier name, asdl_expr_seq * bases, asdl_keyword_seq * - keywords, asdl_stmt_seq * body, asdl_expr_seq * decorator_list, - int lineno, int col_offset, int end_lineno, int end_col_offset, - PyArena *arena) -{ - stmt_ty p; - if (!name) { - PyErr_SetString(PyExc_ValueError, - "field 'name' is required for ClassDef"); - return NULL; - } - p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->kind = ClassDef_kind; - p->v.ClassDef.name = name; - p->v.ClassDef.bases = bases; - p->v.ClassDef.keywords = keywords; - p->v.ClassDef.body = body; - p->v.ClassDef.decorator_list = decorator_list; - p->lineno = lineno; - p->col_offset = col_offset; - p->end_lineno = end_lineno; - p->end_col_offset = end_col_offset; - return p; -} - -stmt_ty -_PyAST_Return(expr_ty value, int lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena) -{ - stmt_ty p; - p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->kind = Return_kind; - p->v.Return.value = value; - p->lineno = lineno; - p->col_offset = col_offset; - p->end_lineno = end_lineno; - p->end_col_offset = end_col_offset; - return p; -} - -stmt_ty -_PyAST_Delete(asdl_expr_seq * targets, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena) -{ - stmt_ty p; - p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->kind = Delete_kind; - p->v.Delete.targets = targets; - p->lineno = lineno; - p->col_offset = col_offset; - p->end_lineno = end_lineno; - p->end_col_offset = end_col_offset; - return p; -} - -stmt_ty -_PyAST_Assign(asdl_expr_seq * targets, expr_ty value, string type_comment, int - lineno, int col_offset, int end_lineno, int end_col_offset, - PyArena *arena) -{ - stmt_ty p; - if (!value) { - PyErr_SetString(PyExc_ValueError, - "field 'value' is required for Assign"); - return NULL; - } - p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->kind = Assign_kind; - p->v.Assign.targets = targets; - p->v.Assign.value = value; - p->v.Assign.type_comment = type_comment; - p->lineno = lineno; - p->col_offset = col_offset; - p->end_lineno = end_lineno; - p->end_col_offset = end_col_offset; - return p; -} - -stmt_ty -_PyAST_AugAssign(expr_ty target, operator_ty op, expr_ty value, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena *arena) -{ - stmt_ty p; - if (!target) { - PyErr_SetString(PyExc_ValueError, - "field 'target' is required for AugAssign"); - return NULL; - } - if (!op) { - PyErr_SetString(PyExc_ValueError, - "field 'op' is required for AugAssign"); - return NULL; - } - if (!value) { - PyErr_SetString(PyExc_ValueError, - "field 'value' is required for AugAssign"); - return NULL; - } - p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->kind = AugAssign_kind; - p->v.AugAssign.target = target; - p->v.AugAssign.op = op; - p->v.AugAssign.value = value; - p->lineno = lineno; - p->col_offset = col_offset; - p->end_lineno = end_lineno; - p->end_col_offset = end_col_offset; - return p; -} - -stmt_ty -_PyAST_AnnAssign(expr_ty target, expr_ty annotation, expr_ty value, int simple, - int lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena) -{ - stmt_ty p; - if (!target) { - PyErr_SetString(PyExc_ValueError, - "field 'target' is required for AnnAssign"); - return NULL; - } - if (!annotation) { - PyErr_SetString(PyExc_ValueError, - "field 'annotation' is required for AnnAssign"); - return NULL; - } - p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->kind = AnnAssign_kind; - p->v.AnnAssign.target = target; - p->v.AnnAssign.annotation = annotation; - p->v.AnnAssign.value = value; - p->v.AnnAssign.simple = simple; - p->lineno = lineno; - p->col_offset = col_offset; - p->end_lineno = end_lineno; - p->end_col_offset = end_col_offset; - return p; -} - -stmt_ty -_PyAST_For(expr_ty target, expr_ty iter, asdl_stmt_seq * body, asdl_stmt_seq * - orelse, string type_comment, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena) -{ - stmt_ty p; - if (!target) { - PyErr_SetString(PyExc_ValueError, - "field 'target' is required for For"); - return NULL; - } - if (!iter) { - PyErr_SetString(PyExc_ValueError, - "field 'iter' is required for For"); - return NULL; - } - p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->kind = For_kind; - p->v.For.target = target; - p->v.For.iter = iter; - p->v.For.body = body; - p->v.For.orelse = orelse; - p->v.For.type_comment = type_comment; - p->lineno = lineno; - p->col_offset = col_offset; - p->end_lineno = end_lineno; - p->end_col_offset = end_col_offset; - return p; -} - -stmt_ty -_PyAST_AsyncFor(expr_ty target, expr_ty iter, asdl_stmt_seq * body, - asdl_stmt_seq * orelse, string type_comment, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena *arena) -{ - stmt_ty p; - if (!target) { - PyErr_SetString(PyExc_ValueError, - "field 'target' is required for AsyncFor"); - return NULL; - } - if (!iter) { - PyErr_SetString(PyExc_ValueError, - "field 'iter' is required for AsyncFor"); - return NULL; - } - p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->kind = AsyncFor_kind; - p->v.AsyncFor.target = target; - p->v.AsyncFor.iter = iter; - p->v.AsyncFor.body = body; - p->v.AsyncFor.orelse = orelse; - p->v.AsyncFor.type_comment = type_comment; - p->lineno = lineno; - p->col_offset = col_offset; - p->end_lineno = end_lineno; - p->end_col_offset = end_col_offset; - return p; -} - -stmt_ty -_PyAST_While(expr_ty test, asdl_stmt_seq * body, asdl_stmt_seq * orelse, int - lineno, int col_offset, int end_lineno, int end_col_offset, - PyArena *arena) -{ - stmt_ty p; - if (!test) { - PyErr_SetString(PyExc_ValueError, - "field 'test' is required for While"); - return NULL; - } - p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->kind = While_kind; - p->v.While.test = test; - p->v.While.body = body; - p->v.While.orelse = orelse; - p->lineno = lineno; - p->col_offset = col_offset; - p->end_lineno = end_lineno; - p->end_col_offset = end_col_offset; - return p; -} - -stmt_ty -_PyAST_If(expr_ty test, asdl_stmt_seq * body, asdl_stmt_seq * orelse, int - lineno, int col_offset, int end_lineno, int end_col_offset, PyArena - *arena) -{ - stmt_ty p; - if (!test) { - PyErr_SetString(PyExc_ValueError, - "field 'test' is required for If"); - return NULL; - } - p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->kind = If_kind; - p->v.If.test = test; - p->v.If.body = body; - p->v.If.orelse = orelse; - p->lineno = lineno; - p->col_offset = col_offset; - p->end_lineno = end_lineno; - p->end_col_offset = end_col_offset; - return p; -} - -stmt_ty -_PyAST_With(asdl_withitem_seq * items, asdl_stmt_seq * body, string - type_comment, int lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena) -{ - stmt_ty p; - p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->kind = With_kind; - p->v.With.items = items; - p->v.With.body = body; - p->v.With.type_comment = type_comment; - p->lineno = lineno; - p->col_offset = col_offset; - p->end_lineno = end_lineno; - p->end_col_offset = end_col_offset; - return p; -} - -stmt_ty -_PyAST_AsyncWith(asdl_withitem_seq * items, asdl_stmt_seq * body, string - type_comment, int lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena) -{ - stmt_ty p; - p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->kind = AsyncWith_kind; - p->v.AsyncWith.items = items; - p->v.AsyncWith.body = body; - p->v.AsyncWith.type_comment = type_comment; - p->lineno = lineno; - p->col_offset = col_offset; - p->end_lineno = end_lineno; - p->end_col_offset = end_col_offset; - return p; -} - -stmt_ty -_PyAST_Match(expr_ty subject, asdl_match_case_seq * cases, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena *arena) -{ - stmt_ty p; - if (!subject) { - PyErr_SetString(PyExc_ValueError, - "field 'subject' is required for Match"); - return NULL; - } - p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->kind = Match_kind; - p->v.Match.subject = subject; - p->v.Match.cases = cases; - p->lineno = lineno; - p->col_offset = col_offset; - p->end_lineno = end_lineno; - p->end_col_offset = end_col_offset; - return p; -} - -stmt_ty -_PyAST_Raise(expr_ty exc, expr_ty cause, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena) -{ - stmt_ty p; - p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->kind = Raise_kind; - p->v.Raise.exc = exc; - p->v.Raise.cause = cause; - p->lineno = lineno; - p->col_offset = col_offset; - p->end_lineno = end_lineno; - p->end_col_offset = end_col_offset; - return p; -} - -stmt_ty -_PyAST_Try(asdl_stmt_seq * body, asdl_excepthandler_seq * handlers, - asdl_stmt_seq * orelse, asdl_stmt_seq * finalbody, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena *arena) -{ - stmt_ty p; - p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->kind = Try_kind; - p->v.Try.body = body; - p->v.Try.handlers = handlers; - p->v.Try.orelse = orelse; - p->v.Try.finalbody = finalbody; - p->lineno = lineno; - p->col_offset = col_offset; - p->end_lineno = end_lineno; - p->end_col_offset = end_col_offset; - return p; -} - -stmt_ty -_PyAST_Assert(expr_ty test, expr_ty msg, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena) -{ - stmt_ty p; - if (!test) { - PyErr_SetString(PyExc_ValueError, - "field 'test' is required for Assert"); - return NULL; - } - p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->kind = Assert_kind; - p->v.Assert.test = test; - p->v.Assert.msg = msg; - p->lineno = lineno; - p->col_offset = col_offset; - p->end_lineno = end_lineno; - p->end_col_offset = end_col_offset; - return p; -} - -stmt_ty -_PyAST_Import(asdl_alias_seq * names, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena) -{ - stmt_ty p; - p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->kind = Import_kind; - p->v.Import.names = names; - p->lineno = lineno; - p->col_offset = col_offset; - p->end_lineno = end_lineno; - p->end_col_offset = end_col_offset; - return p; -} - -stmt_ty -_PyAST_ImportFrom(identifier module, asdl_alias_seq * names, int level, int - lineno, int col_offset, int end_lineno, int end_col_offset, - PyArena *arena) -{ - stmt_ty p; - p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->kind = ImportFrom_kind; - p->v.ImportFrom.module = module; - p->v.ImportFrom.names = names; - p->v.ImportFrom.level = level; - p->lineno = lineno; - p->col_offset = col_offset; - p->end_lineno = end_lineno; - p->end_col_offset = end_col_offset; - return p; -} - -stmt_ty -_PyAST_Global(asdl_identifier_seq * names, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena) -{ - stmt_ty p; - p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->kind = Global_kind; - p->v.Global.names = names; - p->lineno = lineno; - p->col_offset = col_offset; - p->end_lineno = end_lineno; - p->end_col_offset = end_col_offset; - return p; -} - -stmt_ty -_PyAST_Nonlocal(asdl_identifier_seq * names, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena) -{ - stmt_ty p; - p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->kind = Nonlocal_kind; - p->v.Nonlocal.names = names; - p->lineno = lineno; - p->col_offset = col_offset; - p->end_lineno = end_lineno; - p->end_col_offset = end_col_offset; - return p; -} - -stmt_ty -_PyAST_Expr(expr_ty value, int lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena) -{ - stmt_ty p; - if (!value) { - PyErr_SetString(PyExc_ValueError, - "field 'value' is required for Expr"); - return NULL; - } - p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->kind = Expr_kind; - p->v.Expr.value = value; - p->lineno = lineno; - p->col_offset = col_offset; - p->end_lineno = end_lineno; - p->end_col_offset = end_col_offset; - return p; -} - -stmt_ty -_PyAST_Pass(int lineno, int col_offset, int end_lineno, int end_col_offset, - PyArena *arena) -{ - stmt_ty p; - p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->kind = Pass_kind; - p->lineno = lineno; - p->col_offset = col_offset; - p->end_lineno = end_lineno; - p->end_col_offset = end_col_offset; - return p; -} - -stmt_ty -_PyAST_Break(int lineno, int col_offset, int end_lineno, int end_col_offset, - PyArena *arena) -{ - stmt_ty p; - p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->kind = Break_kind; - p->lineno = lineno; - p->col_offset = col_offset; - p->end_lineno = end_lineno; - p->end_col_offset = end_col_offset; - return p; -} - -stmt_ty -_PyAST_Continue(int lineno, int col_offset, int end_lineno, int end_col_offset, - PyArena *arena) -{ - stmt_ty p; - p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->kind = Continue_kind; - p->lineno = lineno; - p->col_offset = col_offset; - p->end_lineno = end_lineno; - p->end_col_offset = end_col_offset; - return p; -} - -expr_ty -_PyAST_BoolOp(boolop_ty op, asdl_expr_seq * values, int lineno, int col_offset, - int end_lineno, int end_col_offset, PyArena *arena) -{ - expr_ty p; - if (!op) { - PyErr_SetString(PyExc_ValueError, - "field 'op' is required for BoolOp"); - return NULL; - } - p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->kind = BoolOp_kind; - p->v.BoolOp.op = op; - p->v.BoolOp.values = values; - p->lineno = lineno; - p->col_offset = col_offset; - p->end_lineno = end_lineno; - p->end_col_offset = end_col_offset; - return p; -} - -expr_ty -_PyAST_NamedExpr(expr_ty target, expr_ty value, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena) -{ - expr_ty p; - if (!target) { - PyErr_SetString(PyExc_ValueError, - "field 'target' is required for NamedExpr"); - return NULL; - } - if (!value) { - PyErr_SetString(PyExc_ValueError, - "field 'value' is required for NamedExpr"); - return NULL; - } - p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->kind = NamedExpr_kind; - p->v.NamedExpr.target = target; - p->v.NamedExpr.value = value; - p->lineno = lineno; - p->col_offset = col_offset; - p->end_lineno = end_lineno; - p->end_col_offset = end_col_offset; - return p; -} - -expr_ty -_PyAST_BinOp(expr_ty left, operator_ty op, expr_ty right, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena *arena) -{ - expr_ty p; - if (!left) { - PyErr_SetString(PyExc_ValueError, - "field 'left' is required for BinOp"); - return NULL; - } - if (!op) { - PyErr_SetString(PyExc_ValueError, - "field 'op' is required for BinOp"); - return NULL; - } - if (!right) { - PyErr_SetString(PyExc_ValueError, - "field 'right' is required for BinOp"); - return NULL; - } - p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->kind = BinOp_kind; - p->v.BinOp.left = left; - p->v.BinOp.op = op; - p->v.BinOp.right = right; - p->lineno = lineno; - p->col_offset = col_offset; - p->end_lineno = end_lineno; - p->end_col_offset = end_col_offset; - return p; -} - -expr_ty -_PyAST_UnaryOp(unaryop_ty op, expr_ty operand, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena) -{ - expr_ty p; - if (!op) { - PyErr_SetString(PyExc_ValueError, - "field 'op' is required for UnaryOp"); - return NULL; - } - if (!operand) { - PyErr_SetString(PyExc_ValueError, - "field 'operand' is required for UnaryOp"); - return NULL; - } - p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->kind = UnaryOp_kind; - p->v.UnaryOp.op = op; - p->v.UnaryOp.operand = operand; - p->lineno = lineno; - p->col_offset = col_offset; - p->end_lineno = end_lineno; - p->end_col_offset = end_col_offset; - return p; -} - -expr_ty -_PyAST_Lambda(arguments_ty args, expr_ty body, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena) -{ - expr_ty p; - if (!args) { - PyErr_SetString(PyExc_ValueError, - "field 'args' is required for Lambda"); - return NULL; - } - if (!body) { - PyErr_SetString(PyExc_ValueError, - "field 'body' is required for Lambda"); - return NULL; - } - p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->kind = Lambda_kind; - p->v.Lambda.args = args; - p->v.Lambda.body = body; - p->lineno = lineno; - p->col_offset = col_offset; - p->end_lineno = end_lineno; - p->end_col_offset = end_col_offset; - return p; -} - -expr_ty -_PyAST_IfExp(expr_ty test, expr_ty body, expr_ty orelse, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena *arena) -{ - expr_ty p; - if (!test) { - PyErr_SetString(PyExc_ValueError, - "field 'test' is required for IfExp"); - return NULL; - } - if (!body) { - PyErr_SetString(PyExc_ValueError, - "field 'body' is required for IfExp"); - return NULL; - } - if (!orelse) { - PyErr_SetString(PyExc_ValueError, - "field 'orelse' is required for IfExp"); - return NULL; - } - p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->kind = IfExp_kind; - p->v.IfExp.test = test; - p->v.IfExp.body = body; - p->v.IfExp.orelse = orelse; - p->lineno = lineno; - p->col_offset = col_offset; - p->end_lineno = end_lineno; - p->end_col_offset = end_col_offset; - return p; -} - -expr_ty -_PyAST_Dict(asdl_expr_seq * keys, asdl_expr_seq * values, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena *arena) -{ - expr_ty p; - p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->kind = Dict_kind; - p->v.Dict.keys = keys; - p->v.Dict.values = values; - p->lineno = lineno; - p->col_offset = col_offset; - p->end_lineno = end_lineno; - p->end_col_offset = end_col_offset; - return p; -} - -expr_ty -_PyAST_Set(asdl_expr_seq * elts, int lineno, int col_offset, int end_lineno, - int end_col_offset, PyArena *arena) -{ - expr_ty p; - p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->kind = Set_kind; - p->v.Set.elts = elts; - p->lineno = lineno; - p->col_offset = col_offset; - p->end_lineno = end_lineno; - p->end_col_offset = end_col_offset; - return p; -} - -expr_ty -_PyAST_ListComp(expr_ty elt, asdl_comprehension_seq * generators, int lineno, - int col_offset, int end_lineno, int end_col_offset, PyArena - *arena) -{ - expr_ty p; - if (!elt) { - PyErr_SetString(PyExc_ValueError, - "field 'elt' is required for ListComp"); - return NULL; - } - p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->kind = ListComp_kind; - p->v.ListComp.elt = elt; - p->v.ListComp.generators = generators; - p->lineno = lineno; - p->col_offset = col_offset; - p->end_lineno = end_lineno; - p->end_col_offset = end_col_offset; - return p; -} - -expr_ty -_PyAST_SetComp(expr_ty elt, asdl_comprehension_seq * generators, int lineno, - int col_offset, int end_lineno, int end_col_offset, PyArena - *arena) -{ - expr_ty p; - if (!elt) { - PyErr_SetString(PyExc_ValueError, - "field 'elt' is required for SetComp"); - return NULL; - } - p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->kind = SetComp_kind; - p->v.SetComp.elt = elt; - p->v.SetComp.generators = generators; - p->lineno = lineno; - p->col_offset = col_offset; - p->end_lineno = end_lineno; - p->end_col_offset = end_col_offset; - return p; -} - -expr_ty -_PyAST_DictComp(expr_ty key, expr_ty value, asdl_comprehension_seq * - generators, int lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena) -{ - expr_ty p; - if (!key) { - PyErr_SetString(PyExc_ValueError, - "field 'key' is required for DictComp"); - return NULL; - } - if (!value) { - PyErr_SetString(PyExc_ValueError, - "field 'value' is required for DictComp"); - return NULL; - } - p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->kind = DictComp_kind; - p->v.DictComp.key = key; - p->v.DictComp.value = value; - p->v.DictComp.generators = generators; - p->lineno = lineno; - p->col_offset = col_offset; - p->end_lineno = end_lineno; - p->end_col_offset = end_col_offset; - return p; -} - -expr_ty -_PyAST_GeneratorExp(expr_ty elt, asdl_comprehension_seq * generators, int - lineno, int col_offset, int end_lineno, int end_col_offset, - PyArena *arena) -{ - expr_ty p; - if (!elt) { - PyErr_SetString(PyExc_ValueError, - "field 'elt' is required for GeneratorExp"); - return NULL; - } - p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->kind = GeneratorExp_kind; - p->v.GeneratorExp.elt = elt; - p->v.GeneratorExp.generators = generators; - p->lineno = lineno; - p->col_offset = col_offset; - p->end_lineno = end_lineno; - p->end_col_offset = end_col_offset; - return p; -} - -expr_ty -_PyAST_Await(expr_ty value, int lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena) -{ - expr_ty p; - if (!value) { - PyErr_SetString(PyExc_ValueError, - "field 'value' is required for Await"); - return NULL; - } - p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->kind = Await_kind; - p->v.Await.value = value; - p->lineno = lineno; - p->col_offset = col_offset; - p->end_lineno = end_lineno; - p->end_col_offset = end_col_offset; - return p; -} - -expr_ty -_PyAST_Yield(expr_ty value, int lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena) -{ - expr_ty p; - p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->kind = Yield_kind; - p->v.Yield.value = value; - p->lineno = lineno; - p->col_offset = col_offset; - p->end_lineno = end_lineno; - p->end_col_offset = end_col_offset; - return p; -} - -expr_ty -_PyAST_YieldFrom(expr_ty value, int lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena) -{ - expr_ty p; - if (!value) { - PyErr_SetString(PyExc_ValueError, - "field 'value' is required for YieldFrom"); - return NULL; - } - p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->kind = YieldFrom_kind; - p->v.YieldFrom.value = value; - p->lineno = lineno; - p->col_offset = col_offset; - p->end_lineno = end_lineno; - p->end_col_offset = end_col_offset; - return p; -} - -expr_ty -_PyAST_Compare(expr_ty left, asdl_int_seq * ops, asdl_expr_seq * comparators, - int lineno, int col_offset, int end_lineno, int end_col_offset, - PyArena *arena) -{ - expr_ty p; - if (!left) { - PyErr_SetString(PyExc_ValueError, - "field 'left' is required for Compare"); - return NULL; - } - p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->kind = Compare_kind; - p->v.Compare.left = left; - p->v.Compare.ops = ops; - p->v.Compare.comparators = comparators; - p->lineno = lineno; - p->col_offset = col_offset; - p->end_lineno = end_lineno; - p->end_col_offset = end_col_offset; - return p; -} - -expr_ty -_PyAST_Call(expr_ty func, asdl_expr_seq * args, asdl_keyword_seq * keywords, - int lineno, int col_offset, int end_lineno, int end_col_offset, - PyArena *arena) -{ - expr_ty p; - if (!func) { - PyErr_SetString(PyExc_ValueError, - "field 'func' is required for Call"); - return NULL; - } - p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->kind = Call_kind; - p->v.Call.func = func; - p->v.Call.args = args; - p->v.Call.keywords = keywords; - p->lineno = lineno; - p->col_offset = col_offset; - p->end_lineno = end_lineno; - p->end_col_offset = end_col_offset; - return p; -} - -expr_ty -_PyAST_FormattedValue(expr_ty value, int conversion, expr_ty format_spec, int - lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena) -{ - expr_ty p; - if (!value) { - PyErr_SetString(PyExc_ValueError, - "field 'value' is required for FormattedValue"); - return NULL; - } - p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->kind = FormattedValue_kind; - p->v.FormattedValue.value = value; - p->v.FormattedValue.conversion = conversion; - p->v.FormattedValue.format_spec = format_spec; - p->lineno = lineno; - p->col_offset = col_offset; - p->end_lineno = end_lineno; - p->end_col_offset = end_col_offset; - return p; -} - -expr_ty -_PyAST_JoinedStr(asdl_expr_seq * values, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena) -{ - expr_ty p; - p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->kind = JoinedStr_kind; - p->v.JoinedStr.values = values; - p->lineno = lineno; - p->col_offset = col_offset; - p->end_lineno = end_lineno; - p->end_col_offset = end_col_offset; - return p; -} - -expr_ty -_PyAST_Constant(constant value, string kind, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena) -{ - expr_ty p; - if (!value) { - PyErr_SetString(PyExc_ValueError, - "field 'value' is required for Constant"); - return NULL; - } - p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->kind = Constant_kind; - p->v.Constant.value = value; - p->v.Constant.kind = kind; - p->lineno = lineno; - p->col_offset = col_offset; - p->end_lineno = end_lineno; - p->end_col_offset = end_col_offset; - return p; -} - -expr_ty -_PyAST_Attribute(expr_ty value, identifier attr, expr_context_ty ctx, int - lineno, int col_offset, int end_lineno, int end_col_offset, - PyArena *arena) -{ - expr_ty p; - if (!value) { - PyErr_SetString(PyExc_ValueError, - "field 'value' is required for Attribute"); - return NULL; - } - if (!attr) { - PyErr_SetString(PyExc_ValueError, - "field 'attr' is required for Attribute"); - return NULL; - } - if (!ctx) { - PyErr_SetString(PyExc_ValueError, - "field 'ctx' is required for Attribute"); - return NULL; - } - p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->kind = Attribute_kind; - p->v.Attribute.value = value; - p->v.Attribute.attr = attr; - p->v.Attribute.ctx = ctx; - p->lineno = lineno; - p->col_offset = col_offset; - p->end_lineno = end_lineno; - p->end_col_offset = end_col_offset; - return p; -} - -expr_ty -_PyAST_Subscript(expr_ty value, expr_ty slice, expr_context_ty ctx, int lineno, - int col_offset, int end_lineno, int end_col_offset, PyArena - *arena) -{ - expr_ty p; - if (!value) { - PyErr_SetString(PyExc_ValueError, - "field 'value' is required for Subscript"); - return NULL; - } - if (!slice) { - PyErr_SetString(PyExc_ValueError, - "field 'slice' is required for Subscript"); - return NULL; - } - if (!ctx) { - PyErr_SetString(PyExc_ValueError, - "field 'ctx' is required for Subscript"); - return NULL; - } - p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->kind = Subscript_kind; - p->v.Subscript.value = value; - p->v.Subscript.slice = slice; - p->v.Subscript.ctx = ctx; - p->lineno = lineno; - p->col_offset = col_offset; - p->end_lineno = end_lineno; - p->end_col_offset = end_col_offset; - return p; -} - -expr_ty -_PyAST_Starred(expr_ty value, expr_context_ty ctx, int lineno, int col_offset, - int end_lineno, int end_col_offset, PyArena *arena) -{ - expr_ty p; - if (!value) { - PyErr_SetString(PyExc_ValueError, - "field 'value' is required for Starred"); - return NULL; - } - if (!ctx) { - PyErr_SetString(PyExc_ValueError, - "field 'ctx' is required for Starred"); - return NULL; - } - p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->kind = Starred_kind; - p->v.Starred.value = value; - p->v.Starred.ctx = ctx; - p->lineno = lineno; - p->col_offset = col_offset; - p->end_lineno = end_lineno; - p->end_col_offset = end_col_offset; - return p; -} - -expr_ty -_PyAST_Name(identifier id, expr_context_ty ctx, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena) -{ - expr_ty p; - if (!id) { - PyErr_SetString(PyExc_ValueError, - "field 'id' is required for Name"); - return NULL; - } - if (!ctx) { - PyErr_SetString(PyExc_ValueError, - "field 'ctx' is required for Name"); - return NULL; - } - p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->kind = Name_kind; - p->v.Name.id = id; - p->v.Name.ctx = ctx; - p->lineno = lineno; - p->col_offset = col_offset; - p->end_lineno = end_lineno; - p->end_col_offset = end_col_offset; - return p; -} - -expr_ty -_PyAST_List(asdl_expr_seq * elts, expr_context_ty ctx, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena *arena) -{ - expr_ty p; - if (!ctx) { - PyErr_SetString(PyExc_ValueError, - "field 'ctx' is required for List"); - return NULL; - } - p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->kind = List_kind; - p->v.List.elts = elts; - p->v.List.ctx = ctx; - p->lineno = lineno; - p->col_offset = col_offset; - p->end_lineno = end_lineno; - p->end_col_offset = end_col_offset; - return p; -} - -expr_ty -_PyAST_Tuple(asdl_expr_seq * elts, expr_context_ty ctx, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena *arena) -{ - expr_ty p; - if (!ctx) { - PyErr_SetString(PyExc_ValueError, - "field 'ctx' is required for Tuple"); - return NULL; - } - p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->kind = Tuple_kind; - p->v.Tuple.elts = elts; - p->v.Tuple.ctx = ctx; - p->lineno = lineno; - p->col_offset = col_offset; - p->end_lineno = end_lineno; - p->end_col_offset = end_col_offset; - return p; -} - -expr_ty -_PyAST_Slice(expr_ty lower, expr_ty upper, expr_ty step, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena *arena) -{ - expr_ty p; - p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->kind = Slice_kind; - p->v.Slice.lower = lower; - p->v.Slice.upper = upper; - p->v.Slice.step = step; - p->lineno = lineno; - p->col_offset = col_offset; - p->end_lineno = end_lineno; - p->end_col_offset = end_col_offset; - return p; -} - -comprehension_ty -_PyAST_comprehension(expr_ty target, expr_ty iter, asdl_expr_seq * ifs, int - is_async, PyArena *arena) -{ - comprehension_ty p; - if (!target) { - PyErr_SetString(PyExc_ValueError, - "field 'target' is required for comprehension"); - return NULL; - } - if (!iter) { - PyErr_SetString(PyExc_ValueError, - "field 'iter' is required for comprehension"); - return NULL; - } - p = (comprehension_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->target = target; - p->iter = iter; - p->ifs = ifs; - p->is_async = is_async; - return p; -} - -excepthandler_ty -_PyAST_ExceptHandler(expr_ty type, identifier name, asdl_stmt_seq * body, int - lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena) -{ - excepthandler_ty p; - p = (excepthandler_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->kind = ExceptHandler_kind; - p->v.ExceptHandler.type = type; - p->v.ExceptHandler.name = name; - p->v.ExceptHandler.body = body; - p->lineno = lineno; - p->col_offset = col_offset; - p->end_lineno = end_lineno; - p->end_col_offset = end_col_offset; - return p; -} - -arguments_ty -_PyAST_arguments(asdl_arg_seq * posonlyargs, asdl_arg_seq * args, arg_ty - vararg, asdl_arg_seq * kwonlyargs, asdl_expr_seq * - kw_defaults, arg_ty kwarg, asdl_expr_seq * defaults, PyArena - *arena) -{ - arguments_ty p; - p = (arguments_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->posonlyargs = posonlyargs; - p->args = args; - p->vararg = vararg; - p->kwonlyargs = kwonlyargs; - p->kw_defaults = kw_defaults; - p->kwarg = kwarg; - p->defaults = defaults; - return p; -} - -arg_ty -_PyAST_arg(identifier arg, expr_ty annotation, string type_comment, int lineno, - int col_offset, int end_lineno, int end_col_offset, PyArena *arena) -{ - arg_ty p; - if (!arg) { - PyErr_SetString(PyExc_ValueError, - "field 'arg' is required for arg"); - return NULL; - } - p = (arg_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->arg = arg; - p->annotation = annotation; - p->type_comment = type_comment; - p->lineno = lineno; - p->col_offset = col_offset; - p->end_lineno = end_lineno; - p->end_col_offset = end_col_offset; - return p; -} - -keyword_ty -_PyAST_keyword(identifier arg, expr_ty value, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena) -{ - keyword_ty p; - if (!value) { - PyErr_SetString(PyExc_ValueError, - "field 'value' is required for keyword"); - return NULL; - } - p = (keyword_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->arg = arg; - p->value = value; - p->lineno = lineno; - p->col_offset = col_offset; - p->end_lineno = end_lineno; - p->end_col_offset = end_col_offset; - return p; -} - -alias_ty -_PyAST_alias(identifier name, identifier asname, int lineno, int col_offset, - int end_lineno, int end_col_offset, PyArena *arena) -{ - alias_ty p; - if (!name) { - PyErr_SetString(PyExc_ValueError, - "field 'name' is required for alias"); - return NULL; - } - p = (alias_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->name = name; - p->asname = asname; - p->lineno = lineno; - p->col_offset = col_offset; - p->end_lineno = end_lineno; - p->end_col_offset = end_col_offset; - return p; -} - -withitem_ty -_PyAST_withitem(expr_ty context_expr, expr_ty optional_vars, PyArena *arena) -{ - withitem_ty p; - if (!context_expr) { - PyErr_SetString(PyExc_ValueError, - "field 'context_expr' is required for withitem"); - return NULL; - } - p = (withitem_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->context_expr = context_expr; - p->optional_vars = optional_vars; - return p; -} - -match_case_ty -_PyAST_match_case(pattern_ty pattern, expr_ty guard, asdl_stmt_seq * body, - PyArena *arena) -{ - match_case_ty p; - if (!pattern) { - PyErr_SetString(PyExc_ValueError, - "field 'pattern' is required for match_case"); - return NULL; - } - p = (match_case_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->pattern = pattern; - p->guard = guard; - p->body = body; - return p; -} - -pattern_ty -_PyAST_MatchValue(expr_ty value, int lineno, int col_offset, int end_lineno, - int end_col_offset, PyArena *arena) -{ - pattern_ty p; - if (!value) { - PyErr_SetString(PyExc_ValueError, - "field 'value' is required for MatchValue"); - return NULL; - } - p = (pattern_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->kind = MatchValue_kind; - p->v.MatchValue.value = value; - p->lineno = lineno; - p->col_offset = col_offset; - p->end_lineno = end_lineno; - p->end_col_offset = end_col_offset; - return p; -} - -pattern_ty -_PyAST_MatchSingleton(constant value, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena) -{ - pattern_ty p; - if (!value) { - PyErr_SetString(PyExc_ValueError, - "field 'value' is required for MatchSingleton"); - return NULL; - } - p = (pattern_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->kind = MatchSingleton_kind; - p->v.MatchSingleton.value = value; - p->lineno = lineno; - p->col_offset = col_offset; - p->end_lineno = end_lineno; - p->end_col_offset = end_col_offset; - return p; -} - -pattern_ty -_PyAST_MatchSequence(asdl_pattern_seq * patterns, int lineno, int col_offset, - int end_lineno, int end_col_offset, PyArena *arena) -{ - pattern_ty p; - p = (pattern_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->kind = MatchSequence_kind; - p->v.MatchSequence.patterns = patterns; - p->lineno = lineno; - p->col_offset = col_offset; - p->end_lineno = end_lineno; - p->end_col_offset = end_col_offset; - return p; -} - -pattern_ty -_PyAST_MatchMapping(asdl_expr_seq * keys, asdl_pattern_seq * patterns, - identifier rest, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena) -{ - pattern_ty p; - p = (pattern_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->kind = MatchMapping_kind; - p->v.MatchMapping.keys = keys; - p->v.MatchMapping.patterns = patterns; - p->v.MatchMapping.rest = rest; - p->lineno = lineno; - p->col_offset = col_offset; - p->end_lineno = end_lineno; - p->end_col_offset = end_col_offset; - return p; -} - -pattern_ty -_PyAST_MatchClass(expr_ty cls, asdl_pattern_seq * patterns, asdl_identifier_seq - * kwd_attrs, asdl_pattern_seq * kwd_patterns, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena - *arena) -{ - pattern_ty p; - if (!cls) { - PyErr_SetString(PyExc_ValueError, - "field 'cls' is required for MatchClass"); - return NULL; - } - p = (pattern_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->kind = MatchClass_kind; - p->v.MatchClass.cls = cls; - p->v.MatchClass.patterns = patterns; - p->v.MatchClass.kwd_attrs = kwd_attrs; - p->v.MatchClass.kwd_patterns = kwd_patterns; - p->lineno = lineno; - p->col_offset = col_offset; - p->end_lineno = end_lineno; - p->end_col_offset = end_col_offset; - return p; -} - -pattern_ty -_PyAST_MatchStar(identifier name, int lineno, int col_offset, int end_lineno, - int end_col_offset, PyArena *arena) -{ - pattern_ty p; - p = (pattern_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->kind = MatchStar_kind; - p->v.MatchStar.name = name; - p->lineno = lineno; - p->col_offset = col_offset; - p->end_lineno = end_lineno; - p->end_col_offset = end_col_offset; - return p; -} - -pattern_ty -_PyAST_MatchAs(pattern_ty pattern, identifier name, int lineno, int col_offset, - int end_lineno, int end_col_offset, PyArena *arena) -{ - pattern_ty p; - p = (pattern_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->kind = MatchAs_kind; - p->v.MatchAs.pattern = pattern; - p->v.MatchAs.name = name; - p->lineno = lineno; - p->col_offset = col_offset; - p->end_lineno = end_lineno; - p->end_col_offset = end_col_offset; - return p; -} - -pattern_ty -_PyAST_MatchOr(asdl_pattern_seq * patterns, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena) -{ - pattern_ty p; - p = (pattern_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->kind = MatchOr_kind; - p->v.MatchOr.patterns = patterns; - p->lineno = lineno; - p->col_offset = col_offset; - p->end_lineno = end_lineno; - p->end_col_offset = end_col_offset; - return p; -} - -type_ignore_ty -_PyAST_TypeIgnore(int lineno, string tag, PyArena *arena) -{ - type_ignore_ty p; - if (!tag) { - PyErr_SetString(PyExc_ValueError, - "field 'tag' is required for TypeIgnore"); - return NULL; - } - p = (type_ignore_ty)_PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->kind = TypeIgnore_kind; - p->v.TypeIgnore.lineno = lineno; - p->v.TypeIgnore.tag = tag; - return p; -} - - -PyObject* -ast2obj_mod(struct ast_state *state, void* _o) -{ - mod_ty o = (mod_ty)_o; - PyObject *result = NULL, *value = NULL; - PyTypeObject *tp; - if (!o) { - Py_RETURN_NONE; - } - switch (o->kind) { - case Module_kind: - tp = (PyTypeObject *)state->Module_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) goto failed; - value = ast2obj_list(state, (asdl_seq*)o->v.Module.body, ast2obj_stmt); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->body, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_list(state, (asdl_seq*)o->v.Module.type_ignores, - ast2obj_type_ignore); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->type_ignores, value) == -1) - goto failed; - Py_DECREF(value); - break; - case Interactive_kind: - tp = (PyTypeObject *)state->Interactive_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) goto failed; - value = ast2obj_list(state, (asdl_seq*)o->v.Interactive.body, - ast2obj_stmt); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->body, value) == -1) - goto failed; - Py_DECREF(value); - break; - case Expression_kind: - tp = (PyTypeObject *)state->Expression_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) goto failed; - value = ast2obj_expr(state, o->v.Expression.body); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->body, value) == -1) - goto failed; - Py_DECREF(value); - break; - case FunctionType_kind: - tp = (PyTypeObject *)state->FunctionType_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) goto failed; - value = ast2obj_list(state, (asdl_seq*)o->v.FunctionType.argtypes, - ast2obj_expr); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->argtypes, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_expr(state, o->v.FunctionType.returns); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->returns, value) == -1) - goto failed; - Py_DECREF(value); - break; - } - return result; -failed: - Py_XDECREF(value); - Py_XDECREF(result); - return NULL; -} - -PyObject* -ast2obj_stmt(struct ast_state *state, void* _o) -{ - stmt_ty o = (stmt_ty)_o; - PyObject *result = NULL, *value = NULL; - PyTypeObject *tp; - if (!o) { - Py_RETURN_NONE; - } - switch (o->kind) { - case FunctionDef_kind: - tp = (PyTypeObject *)state->FunctionDef_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) goto failed; - value = ast2obj_identifier(state, o->v.FunctionDef.name); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->name, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_arguments(state, o->v.FunctionDef.args); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->args, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_list(state, (asdl_seq*)o->v.FunctionDef.body, - ast2obj_stmt); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->body, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_list(state, (asdl_seq*)o->v.FunctionDef.decorator_list, - ast2obj_expr); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->decorator_list, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_expr(state, o->v.FunctionDef.returns); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->returns, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_string(state, o->v.FunctionDef.type_comment); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->type_comment, value) == -1) - goto failed; - Py_DECREF(value); - break; - case AsyncFunctionDef_kind: - tp = (PyTypeObject *)state->AsyncFunctionDef_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) goto failed; - value = ast2obj_identifier(state, o->v.AsyncFunctionDef.name); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->name, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_arguments(state, o->v.AsyncFunctionDef.args); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->args, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_list(state, (asdl_seq*)o->v.AsyncFunctionDef.body, - ast2obj_stmt); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->body, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_list(state, - (asdl_seq*)o->v.AsyncFunctionDef.decorator_list, - ast2obj_expr); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->decorator_list, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_expr(state, o->v.AsyncFunctionDef.returns); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->returns, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_string(state, o->v.AsyncFunctionDef.type_comment); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->type_comment, value) == -1) - goto failed; - Py_DECREF(value); - break; - case ClassDef_kind: - tp = (PyTypeObject *)state->ClassDef_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) goto failed; - value = ast2obj_identifier(state, o->v.ClassDef.name); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->name, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_list(state, (asdl_seq*)o->v.ClassDef.bases, - ast2obj_expr); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->bases, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_list(state, (asdl_seq*)o->v.ClassDef.keywords, - ast2obj_keyword); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->keywords, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_list(state, (asdl_seq*)o->v.ClassDef.body, - ast2obj_stmt); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->body, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_list(state, (asdl_seq*)o->v.ClassDef.decorator_list, - ast2obj_expr); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->decorator_list, value) == -1) - goto failed; - Py_DECREF(value); - break; - case Return_kind: - tp = (PyTypeObject *)state->Return_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) goto failed; - value = ast2obj_expr(state, o->v.Return.value); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->value, value) == -1) - goto failed; - Py_DECREF(value); - break; - case Delete_kind: - tp = (PyTypeObject *)state->Delete_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) goto failed; - value = ast2obj_list(state, (asdl_seq*)o->v.Delete.targets, - ast2obj_expr); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->targets, value) == -1) - goto failed; - Py_DECREF(value); - break; - case Assign_kind: - tp = (PyTypeObject *)state->Assign_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) goto failed; - value = ast2obj_list(state, (asdl_seq*)o->v.Assign.targets, - ast2obj_expr); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->targets, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_expr(state, o->v.Assign.value); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->value, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_string(state, o->v.Assign.type_comment); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->type_comment, value) == -1) - goto failed; - Py_DECREF(value); - break; - case AugAssign_kind: - tp = (PyTypeObject *)state->AugAssign_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) goto failed; - value = ast2obj_expr(state, o->v.AugAssign.target); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->target, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_operator(state, o->v.AugAssign.op); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->op, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_expr(state, o->v.AugAssign.value); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->value, value) == -1) - goto failed; - Py_DECREF(value); - break; - case AnnAssign_kind: - tp = (PyTypeObject *)state->AnnAssign_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) goto failed; - value = ast2obj_expr(state, o->v.AnnAssign.target); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->target, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_expr(state, o->v.AnnAssign.annotation); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->annotation, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_expr(state, o->v.AnnAssign.value); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->value, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_int(state, o->v.AnnAssign.simple); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->simple, value) == -1) - goto failed; - Py_DECREF(value); - break; - case For_kind: - tp = (PyTypeObject *)state->For_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) goto failed; - value = ast2obj_expr(state, o->v.For.target); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->target, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_expr(state, o->v.For.iter); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->iter, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_list(state, (asdl_seq*)o->v.For.body, ast2obj_stmt); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->body, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_list(state, (asdl_seq*)o->v.For.orelse, ast2obj_stmt); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->orelse, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_string(state, o->v.For.type_comment); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->type_comment, value) == -1) - goto failed; - Py_DECREF(value); - break; - case AsyncFor_kind: - tp = (PyTypeObject *)state->AsyncFor_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) goto failed; - value = ast2obj_expr(state, o->v.AsyncFor.target); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->target, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_expr(state, o->v.AsyncFor.iter); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->iter, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_list(state, (asdl_seq*)o->v.AsyncFor.body, - ast2obj_stmt); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->body, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_list(state, (asdl_seq*)o->v.AsyncFor.orelse, - ast2obj_stmt); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->orelse, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_string(state, o->v.AsyncFor.type_comment); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->type_comment, value) == -1) - goto failed; - Py_DECREF(value); - break; - case While_kind: - tp = (PyTypeObject *)state->While_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) goto failed; - value = ast2obj_expr(state, o->v.While.test); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->test, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_list(state, (asdl_seq*)o->v.While.body, ast2obj_stmt); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->body, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_list(state, (asdl_seq*)o->v.While.orelse, ast2obj_stmt); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->orelse, value) == -1) - goto failed; - Py_DECREF(value); - break; - case If_kind: - tp = (PyTypeObject *)state->If_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) goto failed; - value = ast2obj_expr(state, o->v.If.test); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->test, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_list(state, (asdl_seq*)o->v.If.body, ast2obj_stmt); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->body, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_list(state, (asdl_seq*)o->v.If.orelse, ast2obj_stmt); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->orelse, value) == -1) - goto failed; - Py_DECREF(value); - break; - case With_kind: - tp = (PyTypeObject *)state->With_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) goto failed; - value = ast2obj_list(state, (asdl_seq*)o->v.With.items, - ast2obj_withitem); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->items, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_list(state, (asdl_seq*)o->v.With.body, ast2obj_stmt); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->body, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_string(state, o->v.With.type_comment); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->type_comment, value) == -1) - goto failed; - Py_DECREF(value); - break; - case AsyncWith_kind: - tp = (PyTypeObject *)state->AsyncWith_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) goto failed; - value = ast2obj_list(state, (asdl_seq*)o->v.AsyncWith.items, - ast2obj_withitem); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->items, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_list(state, (asdl_seq*)o->v.AsyncWith.body, - ast2obj_stmt); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->body, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_string(state, o->v.AsyncWith.type_comment); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->type_comment, value) == -1) - goto failed; - Py_DECREF(value); - break; - case Match_kind: - tp = (PyTypeObject *)state->Match_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) goto failed; - value = ast2obj_expr(state, o->v.Match.subject); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->subject, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_list(state, (asdl_seq*)o->v.Match.cases, - ast2obj_match_case); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->cases, value) == -1) - goto failed; - Py_DECREF(value); - break; - case Raise_kind: - tp = (PyTypeObject *)state->Raise_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) goto failed; - value = ast2obj_expr(state, o->v.Raise.exc); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->exc, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_expr(state, o->v.Raise.cause); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->cause, value) == -1) - goto failed; - Py_DECREF(value); - break; - case Try_kind: - tp = (PyTypeObject *)state->Try_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) goto failed; - value = ast2obj_list(state, (asdl_seq*)o->v.Try.body, ast2obj_stmt); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->body, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_list(state, (asdl_seq*)o->v.Try.handlers, - ast2obj_excepthandler); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->handlers, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_list(state, (asdl_seq*)o->v.Try.orelse, ast2obj_stmt); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->orelse, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_list(state, (asdl_seq*)o->v.Try.finalbody, - ast2obj_stmt); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->finalbody, value) == -1) - goto failed; - Py_DECREF(value); - break; - case Assert_kind: - tp = (PyTypeObject *)state->Assert_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) goto failed; - value = ast2obj_expr(state, o->v.Assert.test); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->test, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_expr(state, o->v.Assert.msg); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->msg, value) == -1) - goto failed; - Py_DECREF(value); - break; - case Import_kind: - tp = (PyTypeObject *)state->Import_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) goto failed; - value = ast2obj_list(state, (asdl_seq*)o->v.Import.names, - ast2obj_alias); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->names, value) == -1) - goto failed; - Py_DECREF(value); - break; - case ImportFrom_kind: - tp = (PyTypeObject *)state->ImportFrom_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) goto failed; - value = ast2obj_identifier(state, o->v.ImportFrom.module); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->module, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_list(state, (asdl_seq*)o->v.ImportFrom.names, - ast2obj_alias); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->names, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_int(state, o->v.ImportFrom.level); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->level, value) == -1) - goto failed; - Py_DECREF(value); - break; - case Global_kind: - tp = (PyTypeObject *)state->Global_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) goto failed; - value = ast2obj_list(state, (asdl_seq*)o->v.Global.names, - ast2obj_identifier); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->names, value) == -1) - goto failed; - Py_DECREF(value); - break; - case Nonlocal_kind: - tp = (PyTypeObject *)state->Nonlocal_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) goto failed; - value = ast2obj_list(state, (asdl_seq*)o->v.Nonlocal.names, - ast2obj_identifier); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->names, value) == -1) - goto failed; - Py_DECREF(value); - break; - case Expr_kind: - tp = (PyTypeObject *)state->Expr_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) goto failed; - value = ast2obj_expr(state, o->v.Expr.value); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->value, value) == -1) - goto failed; - Py_DECREF(value); - break; - case Pass_kind: - tp = (PyTypeObject *)state->Pass_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) goto failed; - break; - case Break_kind: - tp = (PyTypeObject *)state->Break_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) goto failed; - break; - case Continue_kind: - tp = (PyTypeObject *)state->Continue_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) goto failed; - break; - } - value = ast2obj_int(state, o->lineno); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->lineno, value) < 0) - goto failed; - Py_DECREF(value); - value = ast2obj_int(state, o->col_offset); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->col_offset, value) < 0) - goto failed; - Py_DECREF(value); - value = ast2obj_int(state, o->end_lineno); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->end_lineno, value) < 0) - goto failed; - Py_DECREF(value); - value = ast2obj_int(state, o->end_col_offset); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->end_col_offset, value) < 0) - goto failed; - Py_DECREF(value); - return result; -failed: - Py_XDECREF(value); - Py_XDECREF(result); - return NULL; -} - -PyObject* -ast2obj_expr(struct ast_state *state, void* _o) -{ - expr_ty o = (expr_ty)_o; - PyObject *result = NULL, *value = NULL; - PyTypeObject *tp; - if (!o) { - Py_RETURN_NONE; - } - switch (o->kind) { - case BoolOp_kind: - tp = (PyTypeObject *)state->BoolOp_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) goto failed; - value = ast2obj_boolop(state, o->v.BoolOp.op); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->op, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_list(state, (asdl_seq*)o->v.BoolOp.values, - ast2obj_expr); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->values, value) == -1) - goto failed; - Py_DECREF(value); - break; - case NamedExpr_kind: - tp = (PyTypeObject *)state->NamedExpr_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) goto failed; - value = ast2obj_expr(state, o->v.NamedExpr.target); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->target, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_expr(state, o->v.NamedExpr.value); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->value, value) == -1) - goto failed; - Py_DECREF(value); - break; - case BinOp_kind: - tp = (PyTypeObject *)state->BinOp_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) goto failed; - value = ast2obj_expr(state, o->v.BinOp.left); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->left, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_operator(state, o->v.BinOp.op); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->op, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_expr(state, o->v.BinOp.right); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->right, value) == -1) - goto failed; - Py_DECREF(value); - break; - case UnaryOp_kind: - tp = (PyTypeObject *)state->UnaryOp_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) goto failed; - value = ast2obj_unaryop(state, o->v.UnaryOp.op); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->op, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_expr(state, o->v.UnaryOp.operand); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->operand, value) == -1) - goto failed; - Py_DECREF(value); - break; - case Lambda_kind: - tp = (PyTypeObject *)state->Lambda_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) goto failed; - value = ast2obj_arguments(state, o->v.Lambda.args); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->args, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_expr(state, o->v.Lambda.body); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->body, value) == -1) - goto failed; - Py_DECREF(value); - break; - case IfExp_kind: - tp = (PyTypeObject *)state->IfExp_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) goto failed; - value = ast2obj_expr(state, o->v.IfExp.test); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->test, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_expr(state, o->v.IfExp.body); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->body, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_expr(state, o->v.IfExp.orelse); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->orelse, value) == -1) - goto failed; - Py_DECREF(value); - break; - case Dict_kind: - tp = (PyTypeObject *)state->Dict_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) goto failed; - value = ast2obj_list(state, (asdl_seq*)o->v.Dict.keys, ast2obj_expr); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->keys, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_list(state, (asdl_seq*)o->v.Dict.values, ast2obj_expr); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->values, value) == -1) - goto failed; - Py_DECREF(value); - break; - case Set_kind: - tp = (PyTypeObject *)state->Set_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) goto failed; - value = ast2obj_list(state, (asdl_seq*)o->v.Set.elts, ast2obj_expr); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->elts, value) == -1) - goto failed; - Py_DECREF(value); - break; - case ListComp_kind: - tp = (PyTypeObject *)state->ListComp_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) goto failed; - value = ast2obj_expr(state, o->v.ListComp.elt); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->elt, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_list(state, (asdl_seq*)o->v.ListComp.generators, - ast2obj_comprehension); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->generators, value) == -1) - goto failed; - Py_DECREF(value); - break; - case SetComp_kind: - tp = (PyTypeObject *)state->SetComp_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) goto failed; - value = ast2obj_expr(state, o->v.SetComp.elt); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->elt, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_list(state, (asdl_seq*)o->v.SetComp.generators, - ast2obj_comprehension); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->generators, value) == -1) - goto failed; - Py_DECREF(value); - break; - case DictComp_kind: - tp = (PyTypeObject *)state->DictComp_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) goto failed; - value = ast2obj_expr(state, o->v.DictComp.key); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->key, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_expr(state, o->v.DictComp.value); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->value, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_list(state, (asdl_seq*)o->v.DictComp.generators, - ast2obj_comprehension); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->generators, value) == -1) - goto failed; - Py_DECREF(value); - break; - case GeneratorExp_kind: - tp = (PyTypeObject *)state->GeneratorExp_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) goto failed; - value = ast2obj_expr(state, o->v.GeneratorExp.elt); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->elt, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_list(state, (asdl_seq*)o->v.GeneratorExp.generators, - ast2obj_comprehension); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->generators, value) == -1) - goto failed; - Py_DECREF(value); - break; - case Await_kind: - tp = (PyTypeObject *)state->Await_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) goto failed; - value = ast2obj_expr(state, o->v.Await.value); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->value, value) == -1) - goto failed; - Py_DECREF(value); - break; - case Yield_kind: - tp = (PyTypeObject *)state->Yield_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) goto failed; - value = ast2obj_expr(state, o->v.Yield.value); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->value, value) == -1) - goto failed; - Py_DECREF(value); - break; - case YieldFrom_kind: - tp = (PyTypeObject *)state->YieldFrom_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) goto failed; - value = ast2obj_expr(state, o->v.YieldFrom.value); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->value, value) == -1) - goto failed; - Py_DECREF(value); - break; - case Compare_kind: - tp = (PyTypeObject *)state->Compare_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) goto failed; - value = ast2obj_expr(state, o->v.Compare.left); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->left, value) == -1) - goto failed; - Py_DECREF(value); - { - Py_ssize_t i, n = asdl_seq_LEN(o->v.Compare.ops); - value = PyList_New(n); - if (!value) goto failed; - for(i = 0; i < n; i++) - PyList_SET_ITEM(value, i, ast2obj_cmpop(state, (cmpop_ty)asdl_seq_GET(o->v.Compare.ops, i))); - } - if (!value) goto failed; - if (PyObject_SetAttr(result, state->ops, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_list(state, (asdl_seq*)o->v.Compare.comparators, - ast2obj_expr); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->comparators, value) == -1) - goto failed; - Py_DECREF(value); - break; - case Call_kind: - tp = (PyTypeObject *)state->Call_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) goto failed; - value = ast2obj_expr(state, o->v.Call.func); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->func, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_list(state, (asdl_seq*)o->v.Call.args, ast2obj_expr); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->args, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_list(state, (asdl_seq*)o->v.Call.keywords, - ast2obj_keyword); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->keywords, value) == -1) - goto failed; - Py_DECREF(value); - break; - case FormattedValue_kind: - tp = (PyTypeObject *)state->FormattedValue_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) goto failed; - value = ast2obj_expr(state, o->v.FormattedValue.value); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->value, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_int(state, o->v.FormattedValue.conversion); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->conversion, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_expr(state, o->v.FormattedValue.format_spec); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->format_spec, value) == -1) - goto failed; - Py_DECREF(value); - break; - case JoinedStr_kind: - tp = (PyTypeObject *)state->JoinedStr_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) goto failed; - value = ast2obj_list(state, (asdl_seq*)o->v.JoinedStr.values, - ast2obj_expr); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->values, value) == -1) - goto failed; - Py_DECREF(value); - break; - case Constant_kind: - tp = (PyTypeObject *)state->Constant_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) goto failed; - value = ast2obj_constant(state, o->v.Constant.value); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->value, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_string(state, o->v.Constant.kind); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->kind, value) == -1) - goto failed; - Py_DECREF(value); - break; - case Attribute_kind: - tp = (PyTypeObject *)state->Attribute_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) goto failed; - value = ast2obj_expr(state, o->v.Attribute.value); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->value, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_identifier(state, o->v.Attribute.attr); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->attr, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_expr_context(state, o->v.Attribute.ctx); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->ctx, value) == -1) - goto failed; - Py_DECREF(value); - break; - case Subscript_kind: - tp = (PyTypeObject *)state->Subscript_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) goto failed; - value = ast2obj_expr(state, o->v.Subscript.value); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->value, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_expr(state, o->v.Subscript.slice); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->slice, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_expr_context(state, o->v.Subscript.ctx); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->ctx, value) == -1) - goto failed; - Py_DECREF(value); - break; - case Starred_kind: - tp = (PyTypeObject *)state->Starred_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) goto failed; - value = ast2obj_expr(state, o->v.Starred.value); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->value, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_expr_context(state, o->v.Starred.ctx); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->ctx, value) == -1) - goto failed; - Py_DECREF(value); - break; - case Name_kind: - tp = (PyTypeObject *)state->Name_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) goto failed; - value = ast2obj_identifier(state, o->v.Name.id); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->id, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_expr_context(state, o->v.Name.ctx); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->ctx, value) == -1) - goto failed; - Py_DECREF(value); - break; - case List_kind: - tp = (PyTypeObject *)state->List_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) goto failed; - value = ast2obj_list(state, (asdl_seq*)o->v.List.elts, ast2obj_expr); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->elts, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_expr_context(state, o->v.List.ctx); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->ctx, value) == -1) - goto failed; - Py_DECREF(value); - break; - case Tuple_kind: - tp = (PyTypeObject *)state->Tuple_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) goto failed; - value = ast2obj_list(state, (asdl_seq*)o->v.Tuple.elts, ast2obj_expr); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->elts, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_expr_context(state, o->v.Tuple.ctx); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->ctx, value) == -1) - goto failed; - Py_DECREF(value); - break; - case Slice_kind: - tp = (PyTypeObject *)state->Slice_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) goto failed; - value = ast2obj_expr(state, o->v.Slice.lower); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->lower, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_expr(state, o->v.Slice.upper); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->upper, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_expr(state, o->v.Slice.step); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->step, value) == -1) - goto failed; - Py_DECREF(value); - break; - } - value = ast2obj_int(state, o->lineno); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->lineno, value) < 0) - goto failed; - Py_DECREF(value); - value = ast2obj_int(state, o->col_offset); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->col_offset, value) < 0) - goto failed; - Py_DECREF(value); - value = ast2obj_int(state, o->end_lineno); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->end_lineno, value) < 0) - goto failed; - Py_DECREF(value); - value = ast2obj_int(state, o->end_col_offset); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->end_col_offset, value) < 0) - goto failed; - Py_DECREF(value); - return result; -failed: - Py_XDECREF(value); - Py_XDECREF(result); - return NULL; -} - -PyObject* ast2obj_expr_context(struct ast_state *state, expr_context_ty o) -{ - switch(o) { - case Load: - Py_INCREF(state->Load_singleton); - return state->Load_singleton; - case Store: - Py_INCREF(state->Store_singleton); - return state->Store_singleton; - case Del: - Py_INCREF(state->Del_singleton); - return state->Del_singleton; - } - Py_UNREACHABLE(); -} -PyObject* ast2obj_boolop(struct ast_state *state, boolop_ty o) -{ - switch(o) { - case And: - Py_INCREF(state->And_singleton); - return state->And_singleton; - case Or: - Py_INCREF(state->Or_singleton); - return state->Or_singleton; - } - Py_UNREACHABLE(); -} -PyObject* ast2obj_operator(struct ast_state *state, operator_ty o) -{ - switch(o) { - case Add: - Py_INCREF(state->Add_singleton); - return state->Add_singleton; - case Sub: - Py_INCREF(state->Sub_singleton); - return state->Sub_singleton; - case Mult: - Py_INCREF(state->Mult_singleton); - return state->Mult_singleton; - case MatMult: - Py_INCREF(state->MatMult_singleton); - return state->MatMult_singleton; - case Div: - Py_INCREF(state->Div_singleton); - return state->Div_singleton; - case Mod: - Py_INCREF(state->Mod_singleton); - return state->Mod_singleton; - case Pow: - Py_INCREF(state->Pow_singleton); - return state->Pow_singleton; - case LShift: - Py_INCREF(state->LShift_singleton); - return state->LShift_singleton; - case RShift: - Py_INCREF(state->RShift_singleton); - return state->RShift_singleton; - case BitOr: - Py_INCREF(state->BitOr_singleton); - return state->BitOr_singleton; - case BitXor: - Py_INCREF(state->BitXor_singleton); - return state->BitXor_singleton; - case BitAnd: - Py_INCREF(state->BitAnd_singleton); - return state->BitAnd_singleton; - case FloorDiv: - Py_INCREF(state->FloorDiv_singleton); - return state->FloorDiv_singleton; - } - Py_UNREACHABLE(); -} -PyObject* ast2obj_unaryop(struct ast_state *state, unaryop_ty o) -{ - switch(o) { - case Invert: - Py_INCREF(state->Invert_singleton); - return state->Invert_singleton; - case Not: - Py_INCREF(state->Not_singleton); - return state->Not_singleton; - case UAdd: - Py_INCREF(state->UAdd_singleton); - return state->UAdd_singleton; - case USub: - Py_INCREF(state->USub_singleton); - return state->USub_singleton; - } - Py_UNREACHABLE(); -} -PyObject* ast2obj_cmpop(struct ast_state *state, cmpop_ty o) -{ - switch(o) { - case Eq: - Py_INCREF(state->Eq_singleton); - return state->Eq_singleton; - case NotEq: - Py_INCREF(state->NotEq_singleton); - return state->NotEq_singleton; - case Lt: - Py_INCREF(state->Lt_singleton); - return state->Lt_singleton; - case LtE: - Py_INCREF(state->LtE_singleton); - return state->LtE_singleton; - case Gt: - Py_INCREF(state->Gt_singleton); - return state->Gt_singleton; - case GtE: - Py_INCREF(state->GtE_singleton); - return state->GtE_singleton; - case Is: - Py_INCREF(state->Is_singleton); - return state->Is_singleton; - case IsNot: - Py_INCREF(state->IsNot_singleton); - return state->IsNot_singleton; - case In: - Py_INCREF(state->In_singleton); - return state->In_singleton; - case NotIn: - Py_INCREF(state->NotIn_singleton); - return state->NotIn_singleton; - } - Py_UNREACHABLE(); -} -PyObject* -ast2obj_comprehension(struct ast_state *state, void* _o) -{ - comprehension_ty o = (comprehension_ty)_o; - PyObject *result = NULL, *value = NULL; - PyTypeObject *tp; - if (!o) { - Py_RETURN_NONE; - } - tp = (PyTypeObject *)state->comprehension_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) return NULL; - value = ast2obj_expr(state, o->target); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->target, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_expr(state, o->iter); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->iter, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_list(state, (asdl_seq*)o->ifs, ast2obj_expr); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->ifs, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_int(state, o->is_async); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->is_async, value) == -1) - goto failed; - Py_DECREF(value); - return result; -failed: - Py_XDECREF(value); - Py_XDECREF(result); - return NULL; -} - -PyObject* -ast2obj_excepthandler(struct ast_state *state, void* _o) -{ - excepthandler_ty o = (excepthandler_ty)_o; - PyObject *result = NULL, *value = NULL; - PyTypeObject *tp; - if (!o) { - Py_RETURN_NONE; - } - switch (o->kind) { - case ExceptHandler_kind: - tp = (PyTypeObject *)state->ExceptHandler_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) goto failed; - value = ast2obj_expr(state, o->v.ExceptHandler.type); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->type, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_identifier(state, o->v.ExceptHandler.name); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->name, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_list(state, (asdl_seq*)o->v.ExceptHandler.body, - ast2obj_stmt); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->body, value) == -1) - goto failed; - Py_DECREF(value); - break; - } - value = ast2obj_int(state, o->lineno); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->lineno, value) < 0) - goto failed; - Py_DECREF(value); - value = ast2obj_int(state, o->col_offset); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->col_offset, value) < 0) - goto failed; - Py_DECREF(value); - value = ast2obj_int(state, o->end_lineno); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->end_lineno, value) < 0) - goto failed; - Py_DECREF(value); - value = ast2obj_int(state, o->end_col_offset); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->end_col_offset, value) < 0) - goto failed; - Py_DECREF(value); - return result; -failed: - Py_XDECREF(value); - Py_XDECREF(result); - return NULL; -} - -PyObject* -ast2obj_arguments(struct ast_state *state, void* _o) -{ - arguments_ty o = (arguments_ty)_o; - PyObject *result = NULL, *value = NULL; - PyTypeObject *tp; - if (!o) { - Py_RETURN_NONE; - } - tp = (PyTypeObject *)state->arguments_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) return NULL; - value = ast2obj_list(state, (asdl_seq*)o->posonlyargs, ast2obj_arg); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->posonlyargs, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_list(state, (asdl_seq*)o->args, ast2obj_arg); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->args, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_arg(state, o->vararg); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->vararg, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_list(state, (asdl_seq*)o->kwonlyargs, ast2obj_arg); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->kwonlyargs, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_list(state, (asdl_seq*)o->kw_defaults, ast2obj_expr); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->kw_defaults, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_arg(state, o->kwarg); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->kwarg, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_list(state, (asdl_seq*)o->defaults, ast2obj_expr); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->defaults, value) == -1) - goto failed; - Py_DECREF(value); - return result; -failed: - Py_XDECREF(value); - Py_XDECREF(result); - return NULL; -} - -PyObject* -ast2obj_arg(struct ast_state *state, void* _o) -{ - arg_ty o = (arg_ty)_o; - PyObject *result = NULL, *value = NULL; - PyTypeObject *tp; - if (!o) { - Py_RETURN_NONE; - } - tp = (PyTypeObject *)state->arg_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) return NULL; - value = ast2obj_identifier(state, o->arg); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->arg, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_expr(state, o->annotation); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->annotation, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_string(state, o->type_comment); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->type_comment, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_int(state, o->lineno); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->lineno, value) < 0) - goto failed; - Py_DECREF(value); - value = ast2obj_int(state, o->col_offset); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->col_offset, value) < 0) - goto failed; - Py_DECREF(value); - value = ast2obj_int(state, o->end_lineno); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->end_lineno, value) < 0) - goto failed; - Py_DECREF(value); - value = ast2obj_int(state, o->end_col_offset); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->end_col_offset, value) < 0) - goto failed; - Py_DECREF(value); - return result; -failed: - Py_XDECREF(value); - Py_XDECREF(result); - return NULL; -} - -PyObject* -ast2obj_keyword(struct ast_state *state, void* _o) -{ - keyword_ty o = (keyword_ty)_o; - PyObject *result = NULL, *value = NULL; - PyTypeObject *tp; - if (!o) { - Py_RETURN_NONE; - } - tp = (PyTypeObject *)state->keyword_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) return NULL; - value = ast2obj_identifier(state, o->arg); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->arg, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_expr(state, o->value); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->value, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_int(state, o->lineno); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->lineno, value) < 0) - goto failed; - Py_DECREF(value); - value = ast2obj_int(state, o->col_offset); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->col_offset, value) < 0) - goto failed; - Py_DECREF(value); - value = ast2obj_int(state, o->end_lineno); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->end_lineno, value) < 0) - goto failed; - Py_DECREF(value); - value = ast2obj_int(state, o->end_col_offset); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->end_col_offset, value) < 0) - goto failed; - Py_DECREF(value); - return result; -failed: - Py_XDECREF(value); - Py_XDECREF(result); - return NULL; -} - -PyObject* -ast2obj_alias(struct ast_state *state, void* _o) -{ - alias_ty o = (alias_ty)_o; - PyObject *result = NULL, *value = NULL; - PyTypeObject *tp; - if (!o) { - Py_RETURN_NONE; - } - tp = (PyTypeObject *)state->alias_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) return NULL; - value = ast2obj_identifier(state, o->name); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->name, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_identifier(state, o->asname); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->asname, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_int(state, o->lineno); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->lineno, value) < 0) - goto failed; - Py_DECREF(value); - value = ast2obj_int(state, o->col_offset); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->col_offset, value) < 0) - goto failed; - Py_DECREF(value); - value = ast2obj_int(state, o->end_lineno); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->end_lineno, value) < 0) - goto failed; - Py_DECREF(value); - value = ast2obj_int(state, o->end_col_offset); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->end_col_offset, value) < 0) - goto failed; - Py_DECREF(value); - return result; -failed: - Py_XDECREF(value); - Py_XDECREF(result); - return NULL; -} - -PyObject* -ast2obj_withitem(struct ast_state *state, void* _o) -{ - withitem_ty o = (withitem_ty)_o; - PyObject *result = NULL, *value = NULL; - PyTypeObject *tp; - if (!o) { - Py_RETURN_NONE; - } - tp = (PyTypeObject *)state->withitem_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) return NULL; - value = ast2obj_expr(state, o->context_expr); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->context_expr, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_expr(state, o->optional_vars); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->optional_vars, value) == -1) - goto failed; - Py_DECREF(value); - return result; -failed: - Py_XDECREF(value); - Py_XDECREF(result); - return NULL; -} - -PyObject* -ast2obj_match_case(struct ast_state *state, void* _o) -{ - match_case_ty o = (match_case_ty)_o; - PyObject *result = NULL, *value = NULL; - PyTypeObject *tp; - if (!o) { - Py_RETURN_NONE; - } - tp = (PyTypeObject *)state->match_case_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) return NULL; - value = ast2obj_pattern(state, o->pattern); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->pattern, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_expr(state, o->guard); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->guard, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_list(state, (asdl_seq*)o->body, ast2obj_stmt); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->body, value) == -1) - goto failed; - Py_DECREF(value); - return result; -failed: - Py_XDECREF(value); - Py_XDECREF(result); - return NULL; -} - -PyObject* -ast2obj_pattern(struct ast_state *state, void* _o) -{ - pattern_ty o = (pattern_ty)_o; - PyObject *result = NULL, *value = NULL; - PyTypeObject *tp; - if (!o) { - Py_RETURN_NONE; - } - switch (o->kind) { - case MatchValue_kind: - tp = (PyTypeObject *)state->MatchValue_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) goto failed; - value = ast2obj_expr(state, o->v.MatchValue.value); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->value, value) == -1) - goto failed; - Py_DECREF(value); - break; - case MatchSingleton_kind: - tp = (PyTypeObject *)state->MatchSingleton_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) goto failed; - value = ast2obj_constant(state, o->v.MatchSingleton.value); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->value, value) == -1) - goto failed; - Py_DECREF(value); - break; - case MatchSequence_kind: - tp = (PyTypeObject *)state->MatchSequence_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) goto failed; - value = ast2obj_list(state, (asdl_seq*)o->v.MatchSequence.patterns, - ast2obj_pattern); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->patterns, value) == -1) - goto failed; - Py_DECREF(value); - break; - case MatchMapping_kind: - tp = (PyTypeObject *)state->MatchMapping_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) goto failed; - value = ast2obj_list(state, (asdl_seq*)o->v.MatchMapping.keys, - ast2obj_expr); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->keys, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_list(state, (asdl_seq*)o->v.MatchMapping.patterns, - ast2obj_pattern); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->patterns, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_identifier(state, o->v.MatchMapping.rest); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->rest, value) == -1) - goto failed; - Py_DECREF(value); - break; - case MatchClass_kind: - tp = (PyTypeObject *)state->MatchClass_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) goto failed; - value = ast2obj_expr(state, o->v.MatchClass.cls); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->cls, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_list(state, (asdl_seq*)o->v.MatchClass.patterns, - ast2obj_pattern); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->patterns, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_list(state, (asdl_seq*)o->v.MatchClass.kwd_attrs, - ast2obj_identifier); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->kwd_attrs, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_list(state, (asdl_seq*)o->v.MatchClass.kwd_patterns, - ast2obj_pattern); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->kwd_patterns, value) == -1) - goto failed; - Py_DECREF(value); - break; - case MatchStar_kind: - tp = (PyTypeObject *)state->MatchStar_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) goto failed; - value = ast2obj_identifier(state, o->v.MatchStar.name); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->name, value) == -1) - goto failed; - Py_DECREF(value); - break; - case MatchAs_kind: - tp = (PyTypeObject *)state->MatchAs_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) goto failed; - value = ast2obj_pattern(state, o->v.MatchAs.pattern); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->pattern, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_identifier(state, o->v.MatchAs.name); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->name, value) == -1) - goto failed; - Py_DECREF(value); - break; - case MatchOr_kind: - tp = (PyTypeObject *)state->MatchOr_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) goto failed; - value = ast2obj_list(state, (asdl_seq*)o->v.MatchOr.patterns, - ast2obj_pattern); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->patterns, value) == -1) - goto failed; - Py_DECREF(value); - break; - } - value = ast2obj_int(state, o->lineno); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->lineno, value) < 0) - goto failed; - Py_DECREF(value); - value = ast2obj_int(state, o->col_offset); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->col_offset, value) < 0) - goto failed; - Py_DECREF(value); - value = ast2obj_int(state, o->end_lineno); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->end_lineno, value) < 0) - goto failed; - Py_DECREF(value); - value = ast2obj_int(state, o->end_col_offset); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->end_col_offset, value) < 0) - goto failed; - Py_DECREF(value); - return result; -failed: - Py_XDECREF(value); - Py_XDECREF(result); - return NULL; -} - -PyObject* -ast2obj_type_ignore(struct ast_state *state, void* _o) -{ - type_ignore_ty o = (type_ignore_ty)_o; - PyObject *result = NULL, *value = NULL; - PyTypeObject *tp; - if (!o) { - Py_RETURN_NONE; - } - switch (o->kind) { - case TypeIgnore_kind: - tp = (PyTypeObject *)state->TypeIgnore_type; - result = PyType_GenericNew(tp, NULL, NULL); - if (!result) goto failed; - value = ast2obj_int(state, o->v.TypeIgnore.lineno); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->lineno, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_string(state, o->v.TypeIgnore.tag); - if (!value) goto failed; - if (PyObject_SetAttr(result, state->tag, value) == -1) - goto failed; - Py_DECREF(value); - break; - } - return result; -failed: - Py_XDECREF(value); - Py_XDECREF(result); - return NULL; -} - - -int -obj2ast_mod(struct ast_state *state, PyObject* obj, mod_ty* out, PyArena* arena) -{ - int isinstance; - - PyObject *tmp = NULL; - PyObject *tp; - - if (obj == Py_None) { - *out = NULL; - return 0; - } - tp = state->Module_type; - isinstance = PyObject_IsInstance(obj, tp); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - asdl_stmt_seq* body; - asdl_type_ignore_seq* type_ignores; - - if (_PyObject_LookupAttr(obj, state->body, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from Module"); - return 1; - } - else { - int res; - Py_ssize_t len; - Py_ssize_t i; - if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "Module field \"body\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); - goto failed; - } - len = PyList_GET_SIZE(tmp); - body = _Py_asdl_stmt_seq_new(len, arena); - if (body == NULL) goto failed; - for (i = 0; i < len; i++) { - stmt_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'Module' node")) { - goto failed; - } - res = obj2ast_stmt(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); - Py_DECREF(tmp2); - if (res != 0) goto failed; - if (len != PyList_GET_SIZE(tmp)) { - PyErr_SetString(PyExc_RuntimeError, "Module field \"body\" changed size during iteration"); - goto failed; - } - asdl_seq_SET(body, i, val); - } - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->type_ignores, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"type_ignores\" missing from Module"); - return 1; - } - else { - int res; - Py_ssize_t len; - Py_ssize_t i; - if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "Module field \"type_ignores\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); - goto failed; - } - len = PyList_GET_SIZE(tmp); - type_ignores = _Py_asdl_type_ignore_seq_new(len, arena); - if (type_ignores == NULL) goto failed; - for (i = 0; i < len; i++) { - type_ignore_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'Module' node")) { - goto failed; - } - res = obj2ast_type_ignore(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); - Py_DECREF(tmp2); - if (res != 0) goto failed; - if (len != PyList_GET_SIZE(tmp)) { - PyErr_SetString(PyExc_RuntimeError, "Module field \"type_ignores\" changed size during iteration"); - goto failed; - } - asdl_seq_SET(type_ignores, i, val); - } - Py_CLEAR(tmp); - } - *out = _PyAST_Module(body, type_ignores, arena); - if (*out == NULL) goto failed; - return 0; - } - tp = state->Interactive_type; - isinstance = PyObject_IsInstance(obj, tp); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - asdl_stmt_seq* body; - - if (_PyObject_LookupAttr(obj, state->body, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from Interactive"); - return 1; - } - else { - int res; - Py_ssize_t len; - Py_ssize_t i; - if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "Interactive field \"body\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); - goto failed; - } - len = PyList_GET_SIZE(tmp); - body = _Py_asdl_stmt_seq_new(len, arena); - if (body == NULL) goto failed; - for (i = 0; i < len; i++) { - stmt_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'Interactive' node")) { - goto failed; - } - res = obj2ast_stmt(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); - Py_DECREF(tmp2); - if (res != 0) goto failed; - if (len != PyList_GET_SIZE(tmp)) { - PyErr_SetString(PyExc_RuntimeError, "Interactive field \"body\" changed size during iteration"); - goto failed; - } - asdl_seq_SET(body, i, val); - } - Py_CLEAR(tmp); - } - *out = _PyAST_Interactive(body, arena); - if (*out == NULL) goto failed; - return 0; - } - tp = state->Expression_type; - isinstance = PyObject_IsInstance(obj, tp); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - expr_ty body; - - if (_PyObject_LookupAttr(obj, state->body, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from Expression"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'Expression' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp, &body, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - *out = _PyAST_Expression(body, arena); - if (*out == NULL) goto failed; - return 0; - } - tp = state->FunctionType_type; - isinstance = PyObject_IsInstance(obj, tp); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - asdl_expr_seq* argtypes; - expr_ty returns; - - if (_PyObject_LookupAttr(obj, state->argtypes, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"argtypes\" missing from FunctionType"); - return 1; - } - else { - int res; - Py_ssize_t len; - Py_ssize_t i; - if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "FunctionType field \"argtypes\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); - goto failed; - } - len = PyList_GET_SIZE(tmp); - argtypes = _Py_asdl_expr_seq_new(len, arena); - if (argtypes == NULL) goto failed; - for (i = 0; i < len; i++) { - expr_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'FunctionType' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); - Py_DECREF(tmp2); - if (res != 0) goto failed; - if (len != PyList_GET_SIZE(tmp)) { - PyErr_SetString(PyExc_RuntimeError, "FunctionType field \"argtypes\" changed size during iteration"); - goto failed; - } - asdl_seq_SET(argtypes, i, val); - } - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->returns, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"returns\" missing from FunctionType"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'FunctionType' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp, &returns, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - *out = _PyAST_FunctionType(argtypes, returns, arena); - if (*out == NULL) goto failed; - return 0; - } - - PyErr_Format(PyExc_TypeError, "expected some sort of mod, but got %R", obj); - failed: - Py_XDECREF(tmp); - return 1; -} - -int -obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* - arena) -{ - int isinstance; - - PyObject *tmp = NULL; - PyObject *tp; - int lineno; - int col_offset; - int end_lineno; - int end_col_offset; - - if (obj == Py_None) { - *out = NULL; - return 0; - } - if (_PyObject_LookupAttr(obj, state->lineno, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"lineno\" missing from stmt"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'stmt' node")) { - goto failed; - } - res = obj2ast_int(state, tmp, &lineno, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->col_offset, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"col_offset\" missing from stmt"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'stmt' node")) { - goto failed; - } - res = obj2ast_int(state, tmp, &col_offset, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->end_lineno, &tmp) < 0) { - return 1; - } - if (tmp == NULL || tmp == Py_None) { - Py_CLEAR(tmp); - end_lineno = 0; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'stmt' node")) { - goto failed; - } - res = obj2ast_int(state, tmp, &end_lineno, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->end_col_offset, &tmp) < 0) { - return 1; - } - if (tmp == NULL || tmp == Py_None) { - Py_CLEAR(tmp); - end_col_offset = 0; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'stmt' node")) { - goto failed; - } - res = obj2ast_int(state, tmp, &end_col_offset, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - tp = state->FunctionDef_type; - isinstance = PyObject_IsInstance(obj, tp); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - identifier name; - arguments_ty args; - asdl_stmt_seq* body; - asdl_expr_seq* decorator_list; - expr_ty returns; - string type_comment; - - if (_PyObject_LookupAttr(obj, state->name, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"name\" missing from FunctionDef"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'FunctionDef' node")) { - goto failed; - } - res = obj2ast_identifier(state, tmp, &name, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->args, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"args\" missing from FunctionDef"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'FunctionDef' node")) { - goto failed; - } - res = obj2ast_arguments(state, tmp, &args, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->body, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from FunctionDef"); - return 1; - } - else { - int res; - Py_ssize_t len; - Py_ssize_t i; - if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "FunctionDef field \"body\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); - goto failed; - } - len = PyList_GET_SIZE(tmp); - body = _Py_asdl_stmt_seq_new(len, arena); - if (body == NULL) goto failed; - for (i = 0; i < len; i++) { - stmt_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'FunctionDef' node")) { - goto failed; - } - res = obj2ast_stmt(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); - Py_DECREF(tmp2); - if (res != 0) goto failed; - if (len != PyList_GET_SIZE(tmp)) { - PyErr_SetString(PyExc_RuntimeError, "FunctionDef field \"body\" changed size during iteration"); - goto failed; - } - asdl_seq_SET(body, i, val); - } - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->decorator_list, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"decorator_list\" missing from FunctionDef"); - return 1; - } - else { - int res; - Py_ssize_t len; - Py_ssize_t i; - if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "FunctionDef field \"decorator_list\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); - goto failed; - } - len = PyList_GET_SIZE(tmp); - decorator_list = _Py_asdl_expr_seq_new(len, arena); - if (decorator_list == NULL) goto failed; - for (i = 0; i < len; i++) { - expr_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'FunctionDef' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); - Py_DECREF(tmp2); - if (res != 0) goto failed; - if (len != PyList_GET_SIZE(tmp)) { - PyErr_SetString(PyExc_RuntimeError, "FunctionDef field \"decorator_list\" changed size during iteration"); - goto failed; - } - asdl_seq_SET(decorator_list, i, val); - } - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->returns, &tmp) < 0) { - return 1; - } - if (tmp == NULL || tmp == Py_None) { - Py_CLEAR(tmp); - returns = NULL; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'FunctionDef' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp, &returns, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->type_comment, &tmp) < 0) { - return 1; - } - if (tmp == NULL || tmp == Py_None) { - Py_CLEAR(tmp); - type_comment = NULL; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'FunctionDef' node")) { - goto failed; - } - res = obj2ast_string(state, tmp, &type_comment, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - *out = _PyAST_FunctionDef(name, args, body, decorator_list, returns, - type_comment, lineno, col_offset, end_lineno, - end_col_offset, arena); - if (*out == NULL) goto failed; - return 0; - } - tp = state->AsyncFunctionDef_type; - isinstance = PyObject_IsInstance(obj, tp); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - identifier name; - arguments_ty args; - asdl_stmt_seq* body; - asdl_expr_seq* decorator_list; - expr_ty returns; - string type_comment; - - if (_PyObject_LookupAttr(obj, state->name, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"name\" missing from AsyncFunctionDef"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'AsyncFunctionDef' node")) { - goto failed; - } - res = obj2ast_identifier(state, tmp, &name, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->args, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"args\" missing from AsyncFunctionDef"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'AsyncFunctionDef' node")) { - goto failed; - } - res = obj2ast_arguments(state, tmp, &args, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->body, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from AsyncFunctionDef"); - return 1; - } - else { - int res; - Py_ssize_t len; - Py_ssize_t i; - if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "AsyncFunctionDef field \"body\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); - goto failed; - } - len = PyList_GET_SIZE(tmp); - body = _Py_asdl_stmt_seq_new(len, arena); - if (body == NULL) goto failed; - for (i = 0; i < len; i++) { - stmt_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'AsyncFunctionDef' node")) { - goto failed; - } - res = obj2ast_stmt(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); - Py_DECREF(tmp2); - if (res != 0) goto failed; - if (len != PyList_GET_SIZE(tmp)) { - PyErr_SetString(PyExc_RuntimeError, "AsyncFunctionDef field \"body\" changed size during iteration"); - goto failed; - } - asdl_seq_SET(body, i, val); - } - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->decorator_list, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"decorator_list\" missing from AsyncFunctionDef"); - return 1; - } - else { - int res; - Py_ssize_t len; - Py_ssize_t i; - if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "AsyncFunctionDef field \"decorator_list\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); - goto failed; - } - len = PyList_GET_SIZE(tmp); - decorator_list = _Py_asdl_expr_seq_new(len, arena); - if (decorator_list == NULL) goto failed; - for (i = 0; i < len; i++) { - expr_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'AsyncFunctionDef' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); - Py_DECREF(tmp2); - if (res != 0) goto failed; - if (len != PyList_GET_SIZE(tmp)) { - PyErr_SetString(PyExc_RuntimeError, "AsyncFunctionDef field \"decorator_list\" changed size during iteration"); - goto failed; - } - asdl_seq_SET(decorator_list, i, val); - } - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->returns, &tmp) < 0) { - return 1; - } - if (tmp == NULL || tmp == Py_None) { - Py_CLEAR(tmp); - returns = NULL; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'AsyncFunctionDef' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp, &returns, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->type_comment, &tmp) < 0) { - return 1; - } - if (tmp == NULL || tmp == Py_None) { - Py_CLEAR(tmp); - type_comment = NULL; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'AsyncFunctionDef' node")) { - goto failed; - } - res = obj2ast_string(state, tmp, &type_comment, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - *out = _PyAST_AsyncFunctionDef(name, args, body, decorator_list, - returns, type_comment, lineno, - col_offset, end_lineno, end_col_offset, - arena); - if (*out == NULL) goto failed; - return 0; - } - tp = state->ClassDef_type; - isinstance = PyObject_IsInstance(obj, tp); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - identifier name; - asdl_expr_seq* bases; - asdl_keyword_seq* keywords; - asdl_stmt_seq* body; - asdl_expr_seq* decorator_list; - - if (_PyObject_LookupAttr(obj, state->name, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"name\" missing from ClassDef"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'ClassDef' node")) { - goto failed; - } - res = obj2ast_identifier(state, tmp, &name, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->bases, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"bases\" missing from ClassDef"); - return 1; - } - else { - int res; - Py_ssize_t len; - Py_ssize_t i; - if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "ClassDef field \"bases\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); - goto failed; - } - len = PyList_GET_SIZE(tmp); - bases = _Py_asdl_expr_seq_new(len, arena); - if (bases == NULL) goto failed; - for (i = 0; i < len; i++) { - expr_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'ClassDef' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); - Py_DECREF(tmp2); - if (res != 0) goto failed; - if (len != PyList_GET_SIZE(tmp)) { - PyErr_SetString(PyExc_RuntimeError, "ClassDef field \"bases\" changed size during iteration"); - goto failed; - } - asdl_seq_SET(bases, i, val); - } - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->keywords, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"keywords\" missing from ClassDef"); - return 1; - } - else { - int res; - Py_ssize_t len; - Py_ssize_t i; - if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "ClassDef field \"keywords\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); - goto failed; - } - len = PyList_GET_SIZE(tmp); - keywords = _Py_asdl_keyword_seq_new(len, arena); - if (keywords == NULL) goto failed; - for (i = 0; i < len; i++) { - keyword_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'ClassDef' node")) { - goto failed; - } - res = obj2ast_keyword(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); - Py_DECREF(tmp2); - if (res != 0) goto failed; - if (len != PyList_GET_SIZE(tmp)) { - PyErr_SetString(PyExc_RuntimeError, "ClassDef field \"keywords\" changed size during iteration"); - goto failed; - } - asdl_seq_SET(keywords, i, val); - } - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->body, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from ClassDef"); - return 1; - } - else { - int res; - Py_ssize_t len; - Py_ssize_t i; - if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "ClassDef field \"body\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); - goto failed; - } - len = PyList_GET_SIZE(tmp); - body = _Py_asdl_stmt_seq_new(len, arena); - if (body == NULL) goto failed; - for (i = 0; i < len; i++) { - stmt_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'ClassDef' node")) { - goto failed; - } - res = obj2ast_stmt(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); - Py_DECREF(tmp2); - if (res != 0) goto failed; - if (len != PyList_GET_SIZE(tmp)) { - PyErr_SetString(PyExc_RuntimeError, "ClassDef field \"body\" changed size during iteration"); - goto failed; - } - asdl_seq_SET(body, i, val); - } - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->decorator_list, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"decorator_list\" missing from ClassDef"); - return 1; - } - else { - int res; - Py_ssize_t len; - Py_ssize_t i; - if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "ClassDef field \"decorator_list\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); - goto failed; - } - len = PyList_GET_SIZE(tmp); - decorator_list = _Py_asdl_expr_seq_new(len, arena); - if (decorator_list == NULL) goto failed; - for (i = 0; i < len; i++) { - expr_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'ClassDef' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); - Py_DECREF(tmp2); - if (res != 0) goto failed; - if (len != PyList_GET_SIZE(tmp)) { - PyErr_SetString(PyExc_RuntimeError, "ClassDef field \"decorator_list\" changed size during iteration"); - goto failed; - } - asdl_seq_SET(decorator_list, i, val); - } - Py_CLEAR(tmp); - } - *out = _PyAST_ClassDef(name, bases, keywords, body, decorator_list, - lineno, col_offset, end_lineno, end_col_offset, - arena); - if (*out == NULL) goto failed; - return 0; - } - tp = state->Return_type; - isinstance = PyObject_IsInstance(obj, tp); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - expr_ty value; - - if (_PyObject_LookupAttr(obj, state->value, &tmp) < 0) { - return 1; - } - if (tmp == NULL || tmp == Py_None) { - Py_CLEAR(tmp); - value = NULL; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'Return' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp, &value, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - *out = _PyAST_Return(value, lineno, col_offset, end_lineno, - end_col_offset, arena); - if (*out == NULL) goto failed; - return 0; - } - tp = state->Delete_type; - isinstance = PyObject_IsInstance(obj, tp); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - asdl_expr_seq* targets; - - if (_PyObject_LookupAttr(obj, state->targets, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"targets\" missing from Delete"); - return 1; - } - else { - int res; - Py_ssize_t len; - Py_ssize_t i; - if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "Delete field \"targets\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); - goto failed; - } - len = PyList_GET_SIZE(tmp); - targets = _Py_asdl_expr_seq_new(len, arena); - if (targets == NULL) goto failed; - for (i = 0; i < len; i++) { - expr_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'Delete' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); - Py_DECREF(tmp2); - if (res != 0) goto failed; - if (len != PyList_GET_SIZE(tmp)) { - PyErr_SetString(PyExc_RuntimeError, "Delete field \"targets\" changed size during iteration"); - goto failed; - } - asdl_seq_SET(targets, i, val); - } - Py_CLEAR(tmp); - } - *out = _PyAST_Delete(targets, lineno, col_offset, end_lineno, - end_col_offset, arena); - if (*out == NULL) goto failed; - return 0; - } - tp = state->Assign_type; - isinstance = PyObject_IsInstance(obj, tp); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - asdl_expr_seq* targets; - expr_ty value; - string type_comment; - - if (_PyObject_LookupAttr(obj, state->targets, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"targets\" missing from Assign"); - return 1; - } - else { - int res; - Py_ssize_t len; - Py_ssize_t i; - if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "Assign field \"targets\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); - goto failed; - } - len = PyList_GET_SIZE(tmp); - targets = _Py_asdl_expr_seq_new(len, arena); - if (targets == NULL) goto failed; - for (i = 0; i < len; i++) { - expr_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'Assign' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); - Py_DECREF(tmp2); - if (res != 0) goto failed; - if (len != PyList_GET_SIZE(tmp)) { - PyErr_SetString(PyExc_RuntimeError, "Assign field \"targets\" changed size during iteration"); - goto failed; - } - asdl_seq_SET(targets, i, val); - } - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->value, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from Assign"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'Assign' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp, &value, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->type_comment, &tmp) < 0) { - return 1; - } - if (tmp == NULL || tmp == Py_None) { - Py_CLEAR(tmp); - type_comment = NULL; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'Assign' node")) { - goto failed; - } - res = obj2ast_string(state, tmp, &type_comment, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - *out = _PyAST_Assign(targets, value, type_comment, lineno, col_offset, - end_lineno, end_col_offset, arena); - if (*out == NULL) goto failed; - return 0; - } - tp = state->AugAssign_type; - isinstance = PyObject_IsInstance(obj, tp); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - expr_ty target; - operator_ty op; - expr_ty value; - - if (_PyObject_LookupAttr(obj, state->target, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"target\" missing from AugAssign"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'AugAssign' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp, &target, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->op, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"op\" missing from AugAssign"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'AugAssign' node")) { - goto failed; - } - res = obj2ast_operator(state, tmp, &op, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->value, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from AugAssign"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'AugAssign' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp, &value, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - *out = _PyAST_AugAssign(target, op, value, lineno, col_offset, - end_lineno, end_col_offset, arena); - if (*out == NULL) goto failed; - return 0; - } - tp = state->AnnAssign_type; - isinstance = PyObject_IsInstance(obj, tp); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - expr_ty target; - expr_ty annotation; - expr_ty value; - int simple; - - if (_PyObject_LookupAttr(obj, state->target, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"target\" missing from AnnAssign"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'AnnAssign' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp, &target, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->annotation, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"annotation\" missing from AnnAssign"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'AnnAssign' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp, &annotation, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->value, &tmp) < 0) { - return 1; - } - if (tmp == NULL || tmp == Py_None) { - Py_CLEAR(tmp); - value = NULL; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'AnnAssign' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp, &value, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->simple, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"simple\" missing from AnnAssign"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'AnnAssign' node")) { - goto failed; - } - res = obj2ast_int(state, tmp, &simple, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - *out = _PyAST_AnnAssign(target, annotation, value, simple, lineno, - col_offset, end_lineno, end_col_offset, arena); - if (*out == NULL) goto failed; - return 0; - } - tp = state->For_type; - isinstance = PyObject_IsInstance(obj, tp); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - expr_ty target; - expr_ty iter; - asdl_stmt_seq* body; - asdl_stmt_seq* orelse; - string type_comment; - - if (_PyObject_LookupAttr(obj, state->target, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"target\" missing from For"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'For' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp, &target, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->iter, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"iter\" missing from For"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'For' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp, &iter, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->body, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from For"); - return 1; - } - else { - int res; - Py_ssize_t len; - Py_ssize_t i; - if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "For field \"body\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); - goto failed; - } - len = PyList_GET_SIZE(tmp); - body = _Py_asdl_stmt_seq_new(len, arena); - if (body == NULL) goto failed; - for (i = 0; i < len; i++) { - stmt_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'For' node")) { - goto failed; - } - res = obj2ast_stmt(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); - Py_DECREF(tmp2); - if (res != 0) goto failed; - if (len != PyList_GET_SIZE(tmp)) { - PyErr_SetString(PyExc_RuntimeError, "For field \"body\" changed size during iteration"); - goto failed; - } - asdl_seq_SET(body, i, val); - } - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->orelse, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"orelse\" missing from For"); - return 1; - } - else { - int res; - Py_ssize_t len; - Py_ssize_t i; - if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "For field \"orelse\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); - goto failed; - } - len = PyList_GET_SIZE(tmp); - orelse = _Py_asdl_stmt_seq_new(len, arena); - if (orelse == NULL) goto failed; - for (i = 0; i < len; i++) { - stmt_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'For' node")) { - goto failed; - } - res = obj2ast_stmt(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); - Py_DECREF(tmp2); - if (res != 0) goto failed; - if (len != PyList_GET_SIZE(tmp)) { - PyErr_SetString(PyExc_RuntimeError, "For field \"orelse\" changed size during iteration"); - goto failed; - } - asdl_seq_SET(orelse, i, val); - } - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->type_comment, &tmp) < 0) { - return 1; - } - if (tmp == NULL || tmp == Py_None) { - Py_CLEAR(tmp); - type_comment = NULL; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'For' node")) { - goto failed; - } - res = obj2ast_string(state, tmp, &type_comment, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - *out = _PyAST_For(target, iter, body, orelse, type_comment, lineno, - col_offset, end_lineno, end_col_offset, arena); - if (*out == NULL) goto failed; - return 0; - } - tp = state->AsyncFor_type; - isinstance = PyObject_IsInstance(obj, tp); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - expr_ty target; - expr_ty iter; - asdl_stmt_seq* body; - asdl_stmt_seq* orelse; - string type_comment; - - if (_PyObject_LookupAttr(obj, state->target, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"target\" missing from AsyncFor"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'AsyncFor' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp, &target, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->iter, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"iter\" missing from AsyncFor"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'AsyncFor' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp, &iter, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->body, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from AsyncFor"); - return 1; - } - else { - int res; - Py_ssize_t len; - Py_ssize_t i; - if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "AsyncFor field \"body\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); - goto failed; - } - len = PyList_GET_SIZE(tmp); - body = _Py_asdl_stmt_seq_new(len, arena); - if (body == NULL) goto failed; - for (i = 0; i < len; i++) { - stmt_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'AsyncFor' node")) { - goto failed; - } - res = obj2ast_stmt(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); - Py_DECREF(tmp2); - if (res != 0) goto failed; - if (len != PyList_GET_SIZE(tmp)) { - PyErr_SetString(PyExc_RuntimeError, "AsyncFor field \"body\" changed size during iteration"); - goto failed; - } - asdl_seq_SET(body, i, val); - } - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->orelse, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"orelse\" missing from AsyncFor"); - return 1; - } - else { - int res; - Py_ssize_t len; - Py_ssize_t i; - if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "AsyncFor field \"orelse\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); - goto failed; - } - len = PyList_GET_SIZE(tmp); - orelse = _Py_asdl_stmt_seq_new(len, arena); - if (orelse == NULL) goto failed; - for (i = 0; i < len; i++) { - stmt_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'AsyncFor' node")) { - goto failed; - } - res = obj2ast_stmt(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); - Py_DECREF(tmp2); - if (res != 0) goto failed; - if (len != PyList_GET_SIZE(tmp)) { - PyErr_SetString(PyExc_RuntimeError, "AsyncFor field \"orelse\" changed size during iteration"); - goto failed; - } - asdl_seq_SET(orelse, i, val); - } - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->type_comment, &tmp) < 0) { - return 1; - } - if (tmp == NULL || tmp == Py_None) { - Py_CLEAR(tmp); - type_comment = NULL; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'AsyncFor' node")) { - goto failed; - } - res = obj2ast_string(state, tmp, &type_comment, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - *out = _PyAST_AsyncFor(target, iter, body, orelse, type_comment, - lineno, col_offset, end_lineno, end_col_offset, - arena); - if (*out == NULL) goto failed; - return 0; - } - tp = state->While_type; - isinstance = PyObject_IsInstance(obj, tp); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - expr_ty test; - asdl_stmt_seq* body; - asdl_stmt_seq* orelse; - - if (_PyObject_LookupAttr(obj, state->test, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"test\" missing from While"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'While' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp, &test, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->body, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from While"); - return 1; - } - else { - int res; - Py_ssize_t len; - Py_ssize_t i; - if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "While field \"body\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); - goto failed; - } - len = PyList_GET_SIZE(tmp); - body = _Py_asdl_stmt_seq_new(len, arena); - if (body == NULL) goto failed; - for (i = 0; i < len; i++) { - stmt_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'While' node")) { - goto failed; - } - res = obj2ast_stmt(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); - Py_DECREF(tmp2); - if (res != 0) goto failed; - if (len != PyList_GET_SIZE(tmp)) { - PyErr_SetString(PyExc_RuntimeError, "While field \"body\" changed size during iteration"); - goto failed; - } - asdl_seq_SET(body, i, val); - } - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->orelse, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"orelse\" missing from While"); - return 1; - } - else { - int res; - Py_ssize_t len; - Py_ssize_t i; - if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "While field \"orelse\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); - goto failed; - } - len = PyList_GET_SIZE(tmp); - orelse = _Py_asdl_stmt_seq_new(len, arena); - if (orelse == NULL) goto failed; - for (i = 0; i < len; i++) { - stmt_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'While' node")) { - goto failed; - } - res = obj2ast_stmt(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); - Py_DECREF(tmp2); - if (res != 0) goto failed; - if (len != PyList_GET_SIZE(tmp)) { - PyErr_SetString(PyExc_RuntimeError, "While field \"orelse\" changed size during iteration"); - goto failed; - } - asdl_seq_SET(orelse, i, val); - } - Py_CLEAR(tmp); - } - *out = _PyAST_While(test, body, orelse, lineno, col_offset, end_lineno, - end_col_offset, arena); - if (*out == NULL) goto failed; - return 0; - } - tp = state->If_type; - isinstance = PyObject_IsInstance(obj, tp); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - expr_ty test; - asdl_stmt_seq* body; - asdl_stmt_seq* orelse; - - if (_PyObject_LookupAttr(obj, state->test, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"test\" missing from If"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'If' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp, &test, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->body, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from If"); - return 1; - } - else { - int res; - Py_ssize_t len; - Py_ssize_t i; - if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "If field \"body\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); - goto failed; - } - len = PyList_GET_SIZE(tmp); - body = _Py_asdl_stmt_seq_new(len, arena); - if (body == NULL) goto failed; - for (i = 0; i < len; i++) { - stmt_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'If' node")) { - goto failed; - } - res = obj2ast_stmt(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); - Py_DECREF(tmp2); - if (res != 0) goto failed; - if (len != PyList_GET_SIZE(tmp)) { - PyErr_SetString(PyExc_RuntimeError, "If field \"body\" changed size during iteration"); - goto failed; - } - asdl_seq_SET(body, i, val); - } - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->orelse, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"orelse\" missing from If"); - return 1; - } - else { - int res; - Py_ssize_t len; - Py_ssize_t i; - if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "If field \"orelse\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); - goto failed; - } - len = PyList_GET_SIZE(tmp); - orelse = _Py_asdl_stmt_seq_new(len, arena); - if (orelse == NULL) goto failed; - for (i = 0; i < len; i++) { - stmt_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'If' node")) { - goto failed; - } - res = obj2ast_stmt(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); - Py_DECREF(tmp2); - if (res != 0) goto failed; - if (len != PyList_GET_SIZE(tmp)) { - PyErr_SetString(PyExc_RuntimeError, "If field \"orelse\" changed size during iteration"); - goto failed; - } - asdl_seq_SET(orelse, i, val); - } - Py_CLEAR(tmp); - } - *out = _PyAST_If(test, body, orelse, lineno, col_offset, end_lineno, - end_col_offset, arena); - if (*out == NULL) goto failed; - return 0; - } - tp = state->With_type; - isinstance = PyObject_IsInstance(obj, tp); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - asdl_withitem_seq* items; - asdl_stmt_seq* body; - string type_comment; - - if (_PyObject_LookupAttr(obj, state->items, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"items\" missing from With"); - return 1; - } - else { - int res; - Py_ssize_t len; - Py_ssize_t i; - if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "With field \"items\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); - goto failed; - } - len = PyList_GET_SIZE(tmp); - items = _Py_asdl_withitem_seq_new(len, arena); - if (items == NULL) goto failed; - for (i = 0; i < len; i++) { - withitem_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'With' node")) { - goto failed; - } - res = obj2ast_withitem(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); - Py_DECREF(tmp2); - if (res != 0) goto failed; - if (len != PyList_GET_SIZE(tmp)) { - PyErr_SetString(PyExc_RuntimeError, "With field \"items\" changed size during iteration"); - goto failed; - } - asdl_seq_SET(items, i, val); - } - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->body, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from With"); - return 1; - } - else { - int res; - Py_ssize_t len; - Py_ssize_t i; - if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "With field \"body\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); - goto failed; - } - len = PyList_GET_SIZE(tmp); - body = _Py_asdl_stmt_seq_new(len, arena); - if (body == NULL) goto failed; - for (i = 0; i < len; i++) { - stmt_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'With' node")) { - goto failed; - } - res = obj2ast_stmt(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); - Py_DECREF(tmp2); - if (res != 0) goto failed; - if (len != PyList_GET_SIZE(tmp)) { - PyErr_SetString(PyExc_RuntimeError, "With field \"body\" changed size during iteration"); - goto failed; - } - asdl_seq_SET(body, i, val); - } - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->type_comment, &tmp) < 0) { - return 1; - } - if (tmp == NULL || tmp == Py_None) { - Py_CLEAR(tmp); - type_comment = NULL; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'With' node")) { - goto failed; - } - res = obj2ast_string(state, tmp, &type_comment, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - *out = _PyAST_With(items, body, type_comment, lineno, col_offset, - end_lineno, end_col_offset, arena); - if (*out == NULL) goto failed; - return 0; - } - tp = state->AsyncWith_type; - isinstance = PyObject_IsInstance(obj, tp); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - asdl_withitem_seq* items; - asdl_stmt_seq* body; - string type_comment; - - if (_PyObject_LookupAttr(obj, state->items, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"items\" missing from AsyncWith"); - return 1; - } - else { - int res; - Py_ssize_t len; - Py_ssize_t i; - if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "AsyncWith field \"items\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); - goto failed; - } - len = PyList_GET_SIZE(tmp); - items = _Py_asdl_withitem_seq_new(len, arena); - if (items == NULL) goto failed; - for (i = 0; i < len; i++) { - withitem_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'AsyncWith' node")) { - goto failed; - } - res = obj2ast_withitem(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); - Py_DECREF(tmp2); - if (res != 0) goto failed; - if (len != PyList_GET_SIZE(tmp)) { - PyErr_SetString(PyExc_RuntimeError, "AsyncWith field \"items\" changed size during iteration"); - goto failed; - } - asdl_seq_SET(items, i, val); - } - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->body, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from AsyncWith"); - return 1; - } - else { - int res; - Py_ssize_t len; - Py_ssize_t i; - if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "AsyncWith field \"body\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); - goto failed; - } - len = PyList_GET_SIZE(tmp); - body = _Py_asdl_stmt_seq_new(len, arena); - if (body == NULL) goto failed; - for (i = 0; i < len; i++) { - stmt_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'AsyncWith' node")) { - goto failed; - } - res = obj2ast_stmt(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); - Py_DECREF(tmp2); - if (res != 0) goto failed; - if (len != PyList_GET_SIZE(tmp)) { - PyErr_SetString(PyExc_RuntimeError, "AsyncWith field \"body\" changed size during iteration"); - goto failed; - } - asdl_seq_SET(body, i, val); - } - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->type_comment, &tmp) < 0) { - return 1; - } - if (tmp == NULL || tmp == Py_None) { - Py_CLEAR(tmp); - type_comment = NULL; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'AsyncWith' node")) { - goto failed; - } - res = obj2ast_string(state, tmp, &type_comment, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - *out = _PyAST_AsyncWith(items, body, type_comment, lineno, col_offset, - end_lineno, end_col_offset, arena); - if (*out == NULL) goto failed; - return 0; - } - tp = state->Match_type; - isinstance = PyObject_IsInstance(obj, tp); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - expr_ty subject; - asdl_match_case_seq* cases; - - if (_PyObject_LookupAttr(obj, state->subject, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"subject\" missing from Match"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'Match' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp, &subject, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->cases, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"cases\" missing from Match"); - return 1; - } - else { - int res; - Py_ssize_t len; - Py_ssize_t i; - if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "Match field \"cases\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); - goto failed; - } - len = PyList_GET_SIZE(tmp); - cases = _Py_asdl_match_case_seq_new(len, arena); - if (cases == NULL) goto failed; - for (i = 0; i < len; i++) { - match_case_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'Match' node")) { - goto failed; - } - res = obj2ast_match_case(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); - Py_DECREF(tmp2); - if (res != 0) goto failed; - if (len != PyList_GET_SIZE(tmp)) { - PyErr_SetString(PyExc_RuntimeError, "Match field \"cases\" changed size during iteration"); - goto failed; - } - asdl_seq_SET(cases, i, val); - } - Py_CLEAR(tmp); - } - *out = _PyAST_Match(subject, cases, lineno, col_offset, end_lineno, - end_col_offset, arena); - if (*out == NULL) goto failed; - return 0; - } - tp = state->Raise_type; - isinstance = PyObject_IsInstance(obj, tp); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - expr_ty exc; - expr_ty cause; - - if (_PyObject_LookupAttr(obj, state->exc, &tmp) < 0) { - return 1; - } - if (tmp == NULL || tmp == Py_None) { - Py_CLEAR(tmp); - exc = NULL; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'Raise' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp, &exc, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->cause, &tmp) < 0) { - return 1; - } - if (tmp == NULL || tmp == Py_None) { - Py_CLEAR(tmp); - cause = NULL; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'Raise' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp, &cause, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - *out = _PyAST_Raise(exc, cause, lineno, col_offset, end_lineno, - end_col_offset, arena); - if (*out == NULL) goto failed; - return 0; - } - tp = state->Try_type; - isinstance = PyObject_IsInstance(obj, tp); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - asdl_stmt_seq* body; - asdl_excepthandler_seq* handlers; - asdl_stmt_seq* orelse; - asdl_stmt_seq* finalbody; - - if (_PyObject_LookupAttr(obj, state->body, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from Try"); - return 1; - } - else { - int res; - Py_ssize_t len; - Py_ssize_t i; - if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "Try field \"body\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); - goto failed; - } - len = PyList_GET_SIZE(tmp); - body = _Py_asdl_stmt_seq_new(len, arena); - if (body == NULL) goto failed; - for (i = 0; i < len; i++) { - stmt_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'Try' node")) { - goto failed; - } - res = obj2ast_stmt(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); - Py_DECREF(tmp2); - if (res != 0) goto failed; - if (len != PyList_GET_SIZE(tmp)) { - PyErr_SetString(PyExc_RuntimeError, "Try field \"body\" changed size during iteration"); - goto failed; - } - asdl_seq_SET(body, i, val); - } - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->handlers, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"handlers\" missing from Try"); - return 1; - } - else { - int res; - Py_ssize_t len; - Py_ssize_t i; - if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "Try field \"handlers\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); - goto failed; - } - len = PyList_GET_SIZE(tmp); - handlers = _Py_asdl_excepthandler_seq_new(len, arena); - if (handlers == NULL) goto failed; - for (i = 0; i < len; i++) { - excepthandler_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'Try' node")) { - goto failed; - } - res = obj2ast_excepthandler(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); - Py_DECREF(tmp2); - if (res != 0) goto failed; - if (len != PyList_GET_SIZE(tmp)) { - PyErr_SetString(PyExc_RuntimeError, "Try field \"handlers\" changed size during iteration"); - goto failed; - } - asdl_seq_SET(handlers, i, val); - } - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->orelse, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"orelse\" missing from Try"); - return 1; - } - else { - int res; - Py_ssize_t len; - Py_ssize_t i; - if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "Try field \"orelse\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); - goto failed; - } - len = PyList_GET_SIZE(tmp); - orelse = _Py_asdl_stmt_seq_new(len, arena); - if (orelse == NULL) goto failed; - for (i = 0; i < len; i++) { - stmt_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'Try' node")) { - goto failed; - } - res = obj2ast_stmt(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); - Py_DECREF(tmp2); - if (res != 0) goto failed; - if (len != PyList_GET_SIZE(tmp)) { - PyErr_SetString(PyExc_RuntimeError, "Try field \"orelse\" changed size during iteration"); - goto failed; - } - asdl_seq_SET(orelse, i, val); - } - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->finalbody, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"finalbody\" missing from Try"); - return 1; - } - else { - int res; - Py_ssize_t len; - Py_ssize_t i; - if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "Try field \"finalbody\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); - goto failed; - } - len = PyList_GET_SIZE(tmp); - finalbody = _Py_asdl_stmt_seq_new(len, arena); - if (finalbody == NULL) goto failed; - for (i = 0; i < len; i++) { - stmt_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'Try' node")) { - goto failed; - } - res = obj2ast_stmt(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); - Py_DECREF(tmp2); - if (res != 0) goto failed; - if (len != PyList_GET_SIZE(tmp)) { - PyErr_SetString(PyExc_RuntimeError, "Try field \"finalbody\" changed size during iteration"); - goto failed; - } - asdl_seq_SET(finalbody, i, val); - } - Py_CLEAR(tmp); - } - *out = _PyAST_Try(body, handlers, orelse, finalbody, lineno, - col_offset, end_lineno, end_col_offset, arena); - if (*out == NULL) goto failed; - return 0; - } - tp = state->Assert_type; - isinstance = PyObject_IsInstance(obj, tp); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - expr_ty test; - expr_ty msg; - - if (_PyObject_LookupAttr(obj, state->test, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"test\" missing from Assert"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'Assert' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp, &test, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->msg, &tmp) < 0) { - return 1; - } - if (tmp == NULL || tmp == Py_None) { - Py_CLEAR(tmp); - msg = NULL; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'Assert' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp, &msg, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - *out = _PyAST_Assert(test, msg, lineno, col_offset, end_lineno, - end_col_offset, arena); - if (*out == NULL) goto failed; - return 0; - } - tp = state->Import_type; - isinstance = PyObject_IsInstance(obj, tp); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - asdl_alias_seq* names; - - if (_PyObject_LookupAttr(obj, state->names, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"names\" missing from Import"); - return 1; - } - else { - int res; - Py_ssize_t len; - Py_ssize_t i; - if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "Import field \"names\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); - goto failed; - } - len = PyList_GET_SIZE(tmp); - names = _Py_asdl_alias_seq_new(len, arena); - if (names == NULL) goto failed; - for (i = 0; i < len; i++) { - alias_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'Import' node")) { - goto failed; - } - res = obj2ast_alias(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); - Py_DECREF(tmp2); - if (res != 0) goto failed; - if (len != PyList_GET_SIZE(tmp)) { - PyErr_SetString(PyExc_RuntimeError, "Import field \"names\" changed size during iteration"); - goto failed; - } - asdl_seq_SET(names, i, val); - } - Py_CLEAR(tmp); - } - *out = _PyAST_Import(names, lineno, col_offset, end_lineno, - end_col_offset, arena); - if (*out == NULL) goto failed; - return 0; - } - tp = state->ImportFrom_type; - isinstance = PyObject_IsInstance(obj, tp); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - identifier module; - asdl_alias_seq* names; - int level; - - if (_PyObject_LookupAttr(obj, state->module, &tmp) < 0) { - return 1; - } - if (tmp == NULL || tmp == Py_None) { - Py_CLEAR(tmp); - module = NULL; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'ImportFrom' node")) { - goto failed; - } - res = obj2ast_identifier(state, tmp, &module, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->names, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"names\" missing from ImportFrom"); - return 1; - } - else { - int res; - Py_ssize_t len; - Py_ssize_t i; - if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "ImportFrom field \"names\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); - goto failed; - } - len = PyList_GET_SIZE(tmp); - names = _Py_asdl_alias_seq_new(len, arena); - if (names == NULL) goto failed; - for (i = 0; i < len; i++) { - alias_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'ImportFrom' node")) { - goto failed; - } - res = obj2ast_alias(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); - Py_DECREF(tmp2); - if (res != 0) goto failed; - if (len != PyList_GET_SIZE(tmp)) { - PyErr_SetString(PyExc_RuntimeError, "ImportFrom field \"names\" changed size during iteration"); - goto failed; - } - asdl_seq_SET(names, i, val); - } - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->level, &tmp) < 0) { - return 1; - } - if (tmp == NULL || tmp == Py_None) { - Py_CLEAR(tmp); - level = 0; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'ImportFrom' node")) { - goto failed; - } - res = obj2ast_int(state, tmp, &level, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - *out = _PyAST_ImportFrom(module, names, level, lineno, col_offset, - end_lineno, end_col_offset, arena); - if (*out == NULL) goto failed; - return 0; - } - tp = state->Global_type; - isinstance = PyObject_IsInstance(obj, tp); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - asdl_identifier_seq* names; - - if (_PyObject_LookupAttr(obj, state->names, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"names\" missing from Global"); - return 1; - } - else { - int res; - Py_ssize_t len; - Py_ssize_t i; - if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "Global field \"names\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); - goto failed; - } - len = PyList_GET_SIZE(tmp); - names = _Py_asdl_identifier_seq_new(len, arena); - if (names == NULL) goto failed; - for (i = 0; i < len; i++) { - identifier val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'Global' node")) { - goto failed; - } - res = obj2ast_identifier(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); - Py_DECREF(tmp2); - if (res != 0) goto failed; - if (len != PyList_GET_SIZE(tmp)) { - PyErr_SetString(PyExc_RuntimeError, "Global field \"names\" changed size during iteration"); - goto failed; - } - asdl_seq_SET(names, i, val); - } - Py_CLEAR(tmp); - } - *out = _PyAST_Global(names, lineno, col_offset, end_lineno, - end_col_offset, arena); - if (*out == NULL) goto failed; - return 0; - } - tp = state->Nonlocal_type; - isinstance = PyObject_IsInstance(obj, tp); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - asdl_identifier_seq* names; - - if (_PyObject_LookupAttr(obj, state->names, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"names\" missing from Nonlocal"); - return 1; - } - else { - int res; - Py_ssize_t len; - Py_ssize_t i; - if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "Nonlocal field \"names\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); - goto failed; - } - len = PyList_GET_SIZE(tmp); - names = _Py_asdl_identifier_seq_new(len, arena); - if (names == NULL) goto failed; - for (i = 0; i < len; i++) { - identifier val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'Nonlocal' node")) { - goto failed; - } - res = obj2ast_identifier(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); - Py_DECREF(tmp2); - if (res != 0) goto failed; - if (len != PyList_GET_SIZE(tmp)) { - PyErr_SetString(PyExc_RuntimeError, "Nonlocal field \"names\" changed size during iteration"); - goto failed; - } - asdl_seq_SET(names, i, val); - } - Py_CLEAR(tmp); - } - *out = _PyAST_Nonlocal(names, lineno, col_offset, end_lineno, - end_col_offset, arena); - if (*out == NULL) goto failed; - return 0; - } - tp = state->Expr_type; - isinstance = PyObject_IsInstance(obj, tp); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - expr_ty value; - - if (_PyObject_LookupAttr(obj, state->value, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from Expr"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'Expr' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp, &value, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - *out = _PyAST_Expr(value, lineno, col_offset, end_lineno, - end_col_offset, arena); - if (*out == NULL) goto failed; - return 0; - } - tp = state->Pass_type; - isinstance = PyObject_IsInstance(obj, tp); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - - *out = _PyAST_Pass(lineno, col_offset, end_lineno, end_col_offset, - arena); - if (*out == NULL) goto failed; - return 0; - } - tp = state->Break_type; - isinstance = PyObject_IsInstance(obj, tp); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - - *out = _PyAST_Break(lineno, col_offset, end_lineno, end_col_offset, - arena); - if (*out == NULL) goto failed; - return 0; - } - tp = state->Continue_type; - isinstance = PyObject_IsInstance(obj, tp); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - - *out = _PyAST_Continue(lineno, col_offset, end_lineno, end_col_offset, - arena); - if (*out == NULL) goto failed; - return 0; - } - - PyErr_Format(PyExc_TypeError, "expected some sort of stmt, but got %R", obj); - failed: - Py_XDECREF(tmp); - return 1; -} - -int -obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* - arena) -{ - int isinstance; - - PyObject *tmp = NULL; - PyObject *tp; - int lineno; - int col_offset; - int end_lineno; - int end_col_offset; - - if (obj == Py_None) { - *out = NULL; - return 0; - } - if (_PyObject_LookupAttr(obj, state->lineno, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"lineno\" missing from expr"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'expr' node")) { - goto failed; - } - res = obj2ast_int(state, tmp, &lineno, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->col_offset, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"col_offset\" missing from expr"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'expr' node")) { - goto failed; - } - res = obj2ast_int(state, tmp, &col_offset, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->end_lineno, &tmp) < 0) { - return 1; - } - if (tmp == NULL || tmp == Py_None) { - Py_CLEAR(tmp); - end_lineno = 0; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'expr' node")) { - goto failed; - } - res = obj2ast_int(state, tmp, &end_lineno, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->end_col_offset, &tmp) < 0) { - return 1; - } - if (tmp == NULL || tmp == Py_None) { - Py_CLEAR(tmp); - end_col_offset = 0; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'expr' node")) { - goto failed; - } - res = obj2ast_int(state, tmp, &end_col_offset, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - tp = state->BoolOp_type; - isinstance = PyObject_IsInstance(obj, tp); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - boolop_ty op; - asdl_expr_seq* values; - - if (_PyObject_LookupAttr(obj, state->op, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"op\" missing from BoolOp"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'BoolOp' node")) { - goto failed; - } - res = obj2ast_boolop(state, tmp, &op, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->values, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"values\" missing from BoolOp"); - return 1; - } - else { - int res; - Py_ssize_t len; - Py_ssize_t i; - if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "BoolOp field \"values\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); - goto failed; - } - len = PyList_GET_SIZE(tmp); - values = _Py_asdl_expr_seq_new(len, arena); - if (values == NULL) goto failed; - for (i = 0; i < len; i++) { - expr_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'BoolOp' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); - Py_DECREF(tmp2); - if (res != 0) goto failed; - if (len != PyList_GET_SIZE(tmp)) { - PyErr_SetString(PyExc_RuntimeError, "BoolOp field \"values\" changed size during iteration"); - goto failed; - } - asdl_seq_SET(values, i, val); - } - Py_CLEAR(tmp); - } - *out = _PyAST_BoolOp(op, values, lineno, col_offset, end_lineno, - end_col_offset, arena); - if (*out == NULL) goto failed; - return 0; - } - tp = state->NamedExpr_type; - isinstance = PyObject_IsInstance(obj, tp); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - expr_ty target; - expr_ty value; - - if (_PyObject_LookupAttr(obj, state->target, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"target\" missing from NamedExpr"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'NamedExpr' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp, &target, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->value, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from NamedExpr"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'NamedExpr' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp, &value, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - *out = _PyAST_NamedExpr(target, value, lineno, col_offset, end_lineno, - end_col_offset, arena); - if (*out == NULL) goto failed; - return 0; - } - tp = state->BinOp_type; - isinstance = PyObject_IsInstance(obj, tp); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - expr_ty left; - operator_ty op; - expr_ty right; - - if (_PyObject_LookupAttr(obj, state->left, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"left\" missing from BinOp"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'BinOp' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp, &left, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->op, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"op\" missing from BinOp"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'BinOp' node")) { - goto failed; - } - res = obj2ast_operator(state, tmp, &op, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->right, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"right\" missing from BinOp"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'BinOp' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp, &right, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - *out = _PyAST_BinOp(left, op, right, lineno, col_offset, end_lineno, - end_col_offset, arena); - if (*out == NULL) goto failed; - return 0; - } - tp = state->UnaryOp_type; - isinstance = PyObject_IsInstance(obj, tp); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - unaryop_ty op; - expr_ty operand; - - if (_PyObject_LookupAttr(obj, state->op, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"op\" missing from UnaryOp"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'UnaryOp' node")) { - goto failed; - } - res = obj2ast_unaryop(state, tmp, &op, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->operand, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"operand\" missing from UnaryOp"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'UnaryOp' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp, &operand, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - *out = _PyAST_UnaryOp(op, operand, lineno, col_offset, end_lineno, - end_col_offset, arena); - if (*out == NULL) goto failed; - return 0; - } - tp = state->Lambda_type; - isinstance = PyObject_IsInstance(obj, tp); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - arguments_ty args; - expr_ty body; - - if (_PyObject_LookupAttr(obj, state->args, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"args\" missing from Lambda"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'Lambda' node")) { - goto failed; - } - res = obj2ast_arguments(state, tmp, &args, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->body, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from Lambda"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'Lambda' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp, &body, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - *out = _PyAST_Lambda(args, body, lineno, col_offset, end_lineno, - end_col_offset, arena); - if (*out == NULL) goto failed; - return 0; - } - tp = state->IfExp_type; - isinstance = PyObject_IsInstance(obj, tp); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - expr_ty test; - expr_ty body; - expr_ty orelse; - - if (_PyObject_LookupAttr(obj, state->test, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"test\" missing from IfExp"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'IfExp' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp, &test, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->body, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from IfExp"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'IfExp' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp, &body, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->orelse, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"orelse\" missing from IfExp"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'IfExp' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp, &orelse, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - *out = _PyAST_IfExp(test, body, orelse, lineno, col_offset, end_lineno, - end_col_offset, arena); - if (*out == NULL) goto failed; - return 0; - } - tp = state->Dict_type; - isinstance = PyObject_IsInstance(obj, tp); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - asdl_expr_seq* keys; - asdl_expr_seq* values; - - if (_PyObject_LookupAttr(obj, state->keys, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"keys\" missing from Dict"); - return 1; - } - else { - int res; - Py_ssize_t len; - Py_ssize_t i; - if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "Dict field \"keys\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); - goto failed; - } - len = PyList_GET_SIZE(tmp); - keys = _Py_asdl_expr_seq_new(len, arena); - if (keys == NULL) goto failed; - for (i = 0; i < len; i++) { - expr_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'Dict' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); - Py_DECREF(tmp2); - if (res != 0) goto failed; - if (len != PyList_GET_SIZE(tmp)) { - PyErr_SetString(PyExc_RuntimeError, "Dict field \"keys\" changed size during iteration"); - goto failed; - } - asdl_seq_SET(keys, i, val); - } - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->values, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"values\" missing from Dict"); - return 1; - } - else { - int res; - Py_ssize_t len; - Py_ssize_t i; - if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "Dict field \"values\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); - goto failed; - } - len = PyList_GET_SIZE(tmp); - values = _Py_asdl_expr_seq_new(len, arena); - if (values == NULL) goto failed; - for (i = 0; i < len; i++) { - expr_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'Dict' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); - Py_DECREF(tmp2); - if (res != 0) goto failed; - if (len != PyList_GET_SIZE(tmp)) { - PyErr_SetString(PyExc_RuntimeError, "Dict field \"values\" changed size during iteration"); - goto failed; - } - asdl_seq_SET(values, i, val); - } - Py_CLEAR(tmp); - } - *out = _PyAST_Dict(keys, values, lineno, col_offset, end_lineno, - end_col_offset, arena); - if (*out == NULL) goto failed; - return 0; - } - tp = state->Set_type; - isinstance = PyObject_IsInstance(obj, tp); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - asdl_expr_seq* elts; - - if (_PyObject_LookupAttr(obj, state->elts, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"elts\" missing from Set"); - return 1; - } - else { - int res; - Py_ssize_t len; - Py_ssize_t i; - if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "Set field \"elts\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); - goto failed; - } - len = PyList_GET_SIZE(tmp); - elts = _Py_asdl_expr_seq_new(len, arena); - if (elts == NULL) goto failed; - for (i = 0; i < len; i++) { - expr_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'Set' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); - Py_DECREF(tmp2); - if (res != 0) goto failed; - if (len != PyList_GET_SIZE(tmp)) { - PyErr_SetString(PyExc_RuntimeError, "Set field \"elts\" changed size during iteration"); - goto failed; - } - asdl_seq_SET(elts, i, val); - } - Py_CLEAR(tmp); - } - *out = _PyAST_Set(elts, lineno, col_offset, end_lineno, end_col_offset, - arena); - if (*out == NULL) goto failed; - return 0; - } - tp = state->ListComp_type; - isinstance = PyObject_IsInstance(obj, tp); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - expr_ty elt; - asdl_comprehension_seq* generators; - - if (_PyObject_LookupAttr(obj, state->elt, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"elt\" missing from ListComp"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'ListComp' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp, &elt, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->generators, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"generators\" missing from ListComp"); - return 1; - } - else { - int res; - Py_ssize_t len; - Py_ssize_t i; - if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "ListComp field \"generators\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); - goto failed; - } - len = PyList_GET_SIZE(tmp); - generators = _Py_asdl_comprehension_seq_new(len, arena); - if (generators == NULL) goto failed; - for (i = 0; i < len; i++) { - comprehension_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'ListComp' node")) { - goto failed; - } - res = obj2ast_comprehension(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); - Py_DECREF(tmp2); - if (res != 0) goto failed; - if (len != PyList_GET_SIZE(tmp)) { - PyErr_SetString(PyExc_RuntimeError, "ListComp field \"generators\" changed size during iteration"); - goto failed; - } - asdl_seq_SET(generators, i, val); - } - Py_CLEAR(tmp); - } - *out = _PyAST_ListComp(elt, generators, lineno, col_offset, end_lineno, - end_col_offset, arena); - if (*out == NULL) goto failed; - return 0; - } - tp = state->SetComp_type; - isinstance = PyObject_IsInstance(obj, tp); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - expr_ty elt; - asdl_comprehension_seq* generators; - - if (_PyObject_LookupAttr(obj, state->elt, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"elt\" missing from SetComp"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'SetComp' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp, &elt, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->generators, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"generators\" missing from SetComp"); - return 1; - } - else { - int res; - Py_ssize_t len; - Py_ssize_t i; - if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "SetComp field \"generators\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); - goto failed; - } - len = PyList_GET_SIZE(tmp); - generators = _Py_asdl_comprehension_seq_new(len, arena); - if (generators == NULL) goto failed; - for (i = 0; i < len; i++) { - comprehension_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'SetComp' node")) { - goto failed; - } - res = obj2ast_comprehension(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); - Py_DECREF(tmp2); - if (res != 0) goto failed; - if (len != PyList_GET_SIZE(tmp)) { - PyErr_SetString(PyExc_RuntimeError, "SetComp field \"generators\" changed size during iteration"); - goto failed; - } - asdl_seq_SET(generators, i, val); - } - Py_CLEAR(tmp); - } - *out = _PyAST_SetComp(elt, generators, lineno, col_offset, end_lineno, - end_col_offset, arena); - if (*out == NULL) goto failed; - return 0; - } - tp = state->DictComp_type; - isinstance = PyObject_IsInstance(obj, tp); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - expr_ty key; - expr_ty value; - asdl_comprehension_seq* generators; - - if (_PyObject_LookupAttr(obj, state->key, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"key\" missing from DictComp"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'DictComp' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp, &key, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->value, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from DictComp"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'DictComp' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp, &value, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->generators, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"generators\" missing from DictComp"); - return 1; - } - else { - int res; - Py_ssize_t len; - Py_ssize_t i; - if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "DictComp field \"generators\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); - goto failed; - } - len = PyList_GET_SIZE(tmp); - generators = _Py_asdl_comprehension_seq_new(len, arena); - if (generators == NULL) goto failed; - for (i = 0; i < len; i++) { - comprehension_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'DictComp' node")) { - goto failed; - } - res = obj2ast_comprehension(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); - Py_DECREF(tmp2); - if (res != 0) goto failed; - if (len != PyList_GET_SIZE(tmp)) { - PyErr_SetString(PyExc_RuntimeError, "DictComp field \"generators\" changed size during iteration"); - goto failed; - } - asdl_seq_SET(generators, i, val); - } - Py_CLEAR(tmp); - } - *out = _PyAST_DictComp(key, value, generators, lineno, col_offset, - end_lineno, end_col_offset, arena); - if (*out == NULL) goto failed; - return 0; - } - tp = state->GeneratorExp_type; - isinstance = PyObject_IsInstance(obj, tp); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - expr_ty elt; - asdl_comprehension_seq* generators; - - if (_PyObject_LookupAttr(obj, state->elt, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"elt\" missing from GeneratorExp"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'GeneratorExp' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp, &elt, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->generators, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"generators\" missing from GeneratorExp"); - return 1; - } - else { - int res; - Py_ssize_t len; - Py_ssize_t i; - if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "GeneratorExp field \"generators\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); - goto failed; - } - len = PyList_GET_SIZE(tmp); - generators = _Py_asdl_comprehension_seq_new(len, arena); - if (generators == NULL) goto failed; - for (i = 0; i < len; i++) { - comprehension_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'GeneratorExp' node")) { - goto failed; - } - res = obj2ast_comprehension(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); - Py_DECREF(tmp2); - if (res != 0) goto failed; - if (len != PyList_GET_SIZE(tmp)) { - PyErr_SetString(PyExc_RuntimeError, "GeneratorExp field \"generators\" changed size during iteration"); - goto failed; - } - asdl_seq_SET(generators, i, val); - } - Py_CLEAR(tmp); - } - *out = _PyAST_GeneratorExp(elt, generators, lineno, col_offset, - end_lineno, end_col_offset, arena); - if (*out == NULL) goto failed; - return 0; - } - tp = state->Await_type; - isinstance = PyObject_IsInstance(obj, tp); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - expr_ty value; - - if (_PyObject_LookupAttr(obj, state->value, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from Await"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'Await' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp, &value, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - *out = _PyAST_Await(value, lineno, col_offset, end_lineno, - end_col_offset, arena); - if (*out == NULL) goto failed; - return 0; - } - tp = state->Yield_type; - isinstance = PyObject_IsInstance(obj, tp); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - expr_ty value; - - if (_PyObject_LookupAttr(obj, state->value, &tmp) < 0) { - return 1; - } - if (tmp == NULL || tmp == Py_None) { - Py_CLEAR(tmp); - value = NULL; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'Yield' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp, &value, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - *out = _PyAST_Yield(value, lineno, col_offset, end_lineno, - end_col_offset, arena); - if (*out == NULL) goto failed; - return 0; - } - tp = state->YieldFrom_type; - isinstance = PyObject_IsInstance(obj, tp); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - expr_ty value; - - if (_PyObject_LookupAttr(obj, state->value, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from YieldFrom"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'YieldFrom' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp, &value, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - *out = _PyAST_YieldFrom(value, lineno, col_offset, end_lineno, - end_col_offset, arena); - if (*out == NULL) goto failed; - return 0; - } - tp = state->Compare_type; - isinstance = PyObject_IsInstance(obj, tp); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - expr_ty left; - asdl_int_seq* ops; - asdl_expr_seq* comparators; - - if (_PyObject_LookupAttr(obj, state->left, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"left\" missing from Compare"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'Compare' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp, &left, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->ops, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"ops\" missing from Compare"); - return 1; - } - else { - int res; - Py_ssize_t len; - Py_ssize_t i; - if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "Compare field \"ops\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); - goto failed; - } - len = PyList_GET_SIZE(tmp); - ops = _Py_asdl_int_seq_new(len, arena); - if (ops == NULL) goto failed; - for (i = 0; i < len; i++) { - cmpop_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'Compare' node")) { - goto failed; - } - res = obj2ast_cmpop(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); - Py_DECREF(tmp2); - if (res != 0) goto failed; - if (len != PyList_GET_SIZE(tmp)) { - PyErr_SetString(PyExc_RuntimeError, "Compare field \"ops\" changed size during iteration"); - goto failed; - } - asdl_seq_SET(ops, i, val); - } - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->comparators, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"comparators\" missing from Compare"); - return 1; - } - else { - int res; - Py_ssize_t len; - Py_ssize_t i; - if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "Compare field \"comparators\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); - goto failed; - } - len = PyList_GET_SIZE(tmp); - comparators = _Py_asdl_expr_seq_new(len, arena); - if (comparators == NULL) goto failed; - for (i = 0; i < len; i++) { - expr_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'Compare' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); - Py_DECREF(tmp2); - if (res != 0) goto failed; - if (len != PyList_GET_SIZE(tmp)) { - PyErr_SetString(PyExc_RuntimeError, "Compare field \"comparators\" changed size during iteration"); - goto failed; - } - asdl_seq_SET(comparators, i, val); - } - Py_CLEAR(tmp); - } - *out = _PyAST_Compare(left, ops, comparators, lineno, col_offset, - end_lineno, end_col_offset, arena); - if (*out == NULL) goto failed; - return 0; - } - tp = state->Call_type; - isinstance = PyObject_IsInstance(obj, tp); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - expr_ty func; - asdl_expr_seq* args; - asdl_keyword_seq* keywords; - - if (_PyObject_LookupAttr(obj, state->func, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"func\" missing from Call"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'Call' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp, &func, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->args, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"args\" missing from Call"); - return 1; - } - else { - int res; - Py_ssize_t len; - Py_ssize_t i; - if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "Call field \"args\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); - goto failed; - } - len = PyList_GET_SIZE(tmp); - args = _Py_asdl_expr_seq_new(len, arena); - if (args == NULL) goto failed; - for (i = 0; i < len; i++) { - expr_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'Call' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); - Py_DECREF(tmp2); - if (res != 0) goto failed; - if (len != PyList_GET_SIZE(tmp)) { - PyErr_SetString(PyExc_RuntimeError, "Call field \"args\" changed size during iteration"); - goto failed; - } - asdl_seq_SET(args, i, val); - } - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->keywords, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"keywords\" missing from Call"); - return 1; - } - else { - int res; - Py_ssize_t len; - Py_ssize_t i; - if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "Call field \"keywords\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); - goto failed; - } - len = PyList_GET_SIZE(tmp); - keywords = _Py_asdl_keyword_seq_new(len, arena); - if (keywords == NULL) goto failed; - for (i = 0; i < len; i++) { - keyword_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'Call' node")) { - goto failed; - } - res = obj2ast_keyword(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); - Py_DECREF(tmp2); - if (res != 0) goto failed; - if (len != PyList_GET_SIZE(tmp)) { - PyErr_SetString(PyExc_RuntimeError, "Call field \"keywords\" changed size during iteration"); - goto failed; - } - asdl_seq_SET(keywords, i, val); - } - Py_CLEAR(tmp); - } - *out = _PyAST_Call(func, args, keywords, lineno, col_offset, - end_lineno, end_col_offset, arena); - if (*out == NULL) goto failed; - return 0; - } - tp = state->FormattedValue_type; - isinstance = PyObject_IsInstance(obj, tp); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - expr_ty value; - int conversion; - expr_ty format_spec; - - if (_PyObject_LookupAttr(obj, state->value, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from FormattedValue"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'FormattedValue' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp, &value, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->conversion, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"conversion\" missing from FormattedValue"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'FormattedValue' node")) { - goto failed; - } - res = obj2ast_int(state, tmp, &conversion, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->format_spec, &tmp) < 0) { - return 1; - } - if (tmp == NULL || tmp == Py_None) { - Py_CLEAR(tmp); - format_spec = NULL; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'FormattedValue' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp, &format_spec, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - *out = _PyAST_FormattedValue(value, conversion, format_spec, lineno, - col_offset, end_lineno, end_col_offset, - arena); - if (*out == NULL) goto failed; - return 0; - } - tp = state->JoinedStr_type; - isinstance = PyObject_IsInstance(obj, tp); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - asdl_expr_seq* values; - - if (_PyObject_LookupAttr(obj, state->values, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"values\" missing from JoinedStr"); - return 1; - } - else { - int res; - Py_ssize_t len; - Py_ssize_t i; - if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "JoinedStr field \"values\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); - goto failed; - } - len = PyList_GET_SIZE(tmp); - values = _Py_asdl_expr_seq_new(len, arena); - if (values == NULL) goto failed; - for (i = 0; i < len; i++) { - expr_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'JoinedStr' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); - Py_DECREF(tmp2); - if (res != 0) goto failed; - if (len != PyList_GET_SIZE(tmp)) { - PyErr_SetString(PyExc_RuntimeError, "JoinedStr field \"values\" changed size during iteration"); - goto failed; - } - asdl_seq_SET(values, i, val); - } - Py_CLEAR(tmp); - } - *out = _PyAST_JoinedStr(values, lineno, col_offset, end_lineno, - end_col_offset, arena); - if (*out == NULL) goto failed; - return 0; - } - tp = state->Constant_type; - isinstance = PyObject_IsInstance(obj, tp); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - constant value; - string kind; - - if (_PyObject_LookupAttr(obj, state->value, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from Constant"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'Constant' node")) { - goto failed; - } - res = obj2ast_constant(state, tmp, &value, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->kind, &tmp) < 0) { - return 1; - } - if (tmp == NULL || tmp == Py_None) { - Py_CLEAR(tmp); - kind = NULL; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'Constant' node")) { - goto failed; - } - res = obj2ast_string(state, tmp, &kind, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - *out = _PyAST_Constant(value, kind, lineno, col_offset, end_lineno, - end_col_offset, arena); - if (*out == NULL) goto failed; - return 0; - } - tp = state->Attribute_type; - isinstance = PyObject_IsInstance(obj, tp); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - expr_ty value; - identifier attr; - expr_context_ty ctx; - - if (_PyObject_LookupAttr(obj, state->value, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from Attribute"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'Attribute' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp, &value, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->attr, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"attr\" missing from Attribute"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'Attribute' node")) { - goto failed; - } - res = obj2ast_identifier(state, tmp, &attr, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->ctx, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"ctx\" missing from Attribute"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'Attribute' node")) { - goto failed; - } - res = obj2ast_expr_context(state, tmp, &ctx, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - *out = _PyAST_Attribute(value, attr, ctx, lineno, col_offset, - end_lineno, end_col_offset, arena); - if (*out == NULL) goto failed; - return 0; - } - tp = state->Subscript_type; - isinstance = PyObject_IsInstance(obj, tp); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - expr_ty value; - expr_ty slice; - expr_context_ty ctx; - - if (_PyObject_LookupAttr(obj, state->value, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from Subscript"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'Subscript' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp, &value, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->slice, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"slice\" missing from Subscript"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'Subscript' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp, &slice, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->ctx, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"ctx\" missing from Subscript"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'Subscript' node")) { - goto failed; - } - res = obj2ast_expr_context(state, tmp, &ctx, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - *out = _PyAST_Subscript(value, slice, ctx, lineno, col_offset, - end_lineno, end_col_offset, arena); - if (*out == NULL) goto failed; - return 0; - } - tp = state->Starred_type; - isinstance = PyObject_IsInstance(obj, tp); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - expr_ty value; - expr_context_ty ctx; - - if (_PyObject_LookupAttr(obj, state->value, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from Starred"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'Starred' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp, &value, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->ctx, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"ctx\" missing from Starred"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'Starred' node")) { - goto failed; - } - res = obj2ast_expr_context(state, tmp, &ctx, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - *out = _PyAST_Starred(value, ctx, lineno, col_offset, end_lineno, - end_col_offset, arena); - if (*out == NULL) goto failed; - return 0; - } - tp = state->Name_type; - isinstance = PyObject_IsInstance(obj, tp); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - identifier id; - expr_context_ty ctx; - - if (_PyObject_LookupAttr(obj, state->id, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"id\" missing from Name"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'Name' node")) { - goto failed; - } - res = obj2ast_identifier(state, tmp, &id, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->ctx, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"ctx\" missing from Name"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'Name' node")) { - goto failed; - } - res = obj2ast_expr_context(state, tmp, &ctx, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - *out = _PyAST_Name(id, ctx, lineno, col_offset, end_lineno, - end_col_offset, arena); - if (*out == NULL) goto failed; - return 0; - } - tp = state->List_type; - isinstance = PyObject_IsInstance(obj, tp); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - asdl_expr_seq* elts; - expr_context_ty ctx; - - if (_PyObject_LookupAttr(obj, state->elts, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"elts\" missing from List"); - return 1; - } - else { - int res; - Py_ssize_t len; - Py_ssize_t i; - if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "List field \"elts\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); - goto failed; - } - len = PyList_GET_SIZE(tmp); - elts = _Py_asdl_expr_seq_new(len, arena); - if (elts == NULL) goto failed; - for (i = 0; i < len; i++) { - expr_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'List' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); - Py_DECREF(tmp2); - if (res != 0) goto failed; - if (len != PyList_GET_SIZE(tmp)) { - PyErr_SetString(PyExc_RuntimeError, "List field \"elts\" changed size during iteration"); - goto failed; - } - asdl_seq_SET(elts, i, val); - } - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->ctx, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"ctx\" missing from List"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'List' node")) { - goto failed; - } - res = obj2ast_expr_context(state, tmp, &ctx, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - *out = _PyAST_List(elts, ctx, lineno, col_offset, end_lineno, - end_col_offset, arena); - if (*out == NULL) goto failed; - return 0; - } - tp = state->Tuple_type; - isinstance = PyObject_IsInstance(obj, tp); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - asdl_expr_seq* elts; - expr_context_ty ctx; - - if (_PyObject_LookupAttr(obj, state->elts, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"elts\" missing from Tuple"); - return 1; - } - else { - int res; - Py_ssize_t len; - Py_ssize_t i; - if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "Tuple field \"elts\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); - goto failed; - } - len = PyList_GET_SIZE(tmp); - elts = _Py_asdl_expr_seq_new(len, arena); - if (elts == NULL) goto failed; - for (i = 0; i < len; i++) { - expr_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'Tuple' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); - Py_DECREF(tmp2); - if (res != 0) goto failed; - if (len != PyList_GET_SIZE(tmp)) { - PyErr_SetString(PyExc_RuntimeError, "Tuple field \"elts\" changed size during iteration"); - goto failed; - } - asdl_seq_SET(elts, i, val); - } - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->ctx, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"ctx\" missing from Tuple"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'Tuple' node")) { - goto failed; - } - res = obj2ast_expr_context(state, tmp, &ctx, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - *out = _PyAST_Tuple(elts, ctx, lineno, col_offset, end_lineno, - end_col_offset, arena); - if (*out == NULL) goto failed; - return 0; - } - tp = state->Slice_type; - isinstance = PyObject_IsInstance(obj, tp); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - expr_ty lower; - expr_ty upper; - expr_ty step; - - if (_PyObject_LookupAttr(obj, state->lower, &tmp) < 0) { - return 1; - } - if (tmp == NULL || tmp == Py_None) { - Py_CLEAR(tmp); - lower = NULL; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'Slice' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp, &lower, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->upper, &tmp) < 0) { - return 1; - } - if (tmp == NULL || tmp == Py_None) { - Py_CLEAR(tmp); - upper = NULL; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'Slice' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp, &upper, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->step, &tmp) < 0) { - return 1; - } - if (tmp == NULL || tmp == Py_None) { - Py_CLEAR(tmp); - step = NULL; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'Slice' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp, &step, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - *out = _PyAST_Slice(lower, upper, step, lineno, col_offset, end_lineno, - end_col_offset, arena); - if (*out == NULL) goto failed; - return 0; - } - - PyErr_Format(PyExc_TypeError, "expected some sort of expr, but got %R", obj); - failed: - Py_XDECREF(tmp); - return 1; -} - -int -obj2ast_expr_context(struct ast_state *state, PyObject* obj, expr_context_ty* - out, PyArena* arena) -{ - int isinstance; - - isinstance = PyObject_IsInstance(obj, state->Load_type); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - *out = Load; - return 0; - } - isinstance = PyObject_IsInstance(obj, state->Store_type); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - *out = Store; - return 0; - } - isinstance = PyObject_IsInstance(obj, state->Del_type); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - *out = Del; - return 0; - } - - PyErr_Format(PyExc_TypeError, "expected some sort of expr_context, but got %R", obj); - return 1; -} - -int -obj2ast_boolop(struct ast_state *state, PyObject* obj, boolop_ty* out, PyArena* - arena) -{ - int isinstance; - - isinstance = PyObject_IsInstance(obj, state->And_type); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - *out = And; - return 0; - } - isinstance = PyObject_IsInstance(obj, state->Or_type); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - *out = Or; - return 0; - } - - PyErr_Format(PyExc_TypeError, "expected some sort of boolop, but got %R", obj); - return 1; -} - -int -obj2ast_operator(struct ast_state *state, PyObject* obj, operator_ty* out, - PyArena* arena) -{ - int isinstance; - - isinstance = PyObject_IsInstance(obj, state->Add_type); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - *out = Add; - return 0; - } - isinstance = PyObject_IsInstance(obj, state->Sub_type); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - *out = Sub; - return 0; - } - isinstance = PyObject_IsInstance(obj, state->Mult_type); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - *out = Mult; - return 0; - } - isinstance = PyObject_IsInstance(obj, state->MatMult_type); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - *out = MatMult; - return 0; - } - isinstance = PyObject_IsInstance(obj, state->Div_type); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - *out = Div; - return 0; - } - isinstance = PyObject_IsInstance(obj, state->Mod_type); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - *out = Mod; - return 0; - } - isinstance = PyObject_IsInstance(obj, state->Pow_type); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - *out = Pow; - return 0; - } - isinstance = PyObject_IsInstance(obj, state->LShift_type); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - *out = LShift; - return 0; - } - isinstance = PyObject_IsInstance(obj, state->RShift_type); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - *out = RShift; - return 0; - } - isinstance = PyObject_IsInstance(obj, state->BitOr_type); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - *out = BitOr; - return 0; - } - isinstance = PyObject_IsInstance(obj, state->BitXor_type); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - *out = BitXor; - return 0; - } - isinstance = PyObject_IsInstance(obj, state->BitAnd_type); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - *out = BitAnd; - return 0; - } - isinstance = PyObject_IsInstance(obj, state->FloorDiv_type); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - *out = FloorDiv; - return 0; - } - - PyErr_Format(PyExc_TypeError, "expected some sort of operator, but got %R", obj); - return 1; -} - -int -obj2ast_unaryop(struct ast_state *state, PyObject* obj, unaryop_ty* out, - PyArena* arena) -{ - int isinstance; - - isinstance = PyObject_IsInstance(obj, state->Invert_type); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - *out = Invert; - return 0; - } - isinstance = PyObject_IsInstance(obj, state->Not_type); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - *out = Not; - return 0; - } - isinstance = PyObject_IsInstance(obj, state->UAdd_type); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - *out = UAdd; - return 0; - } - isinstance = PyObject_IsInstance(obj, state->USub_type); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - *out = USub; - return 0; - } - - PyErr_Format(PyExc_TypeError, "expected some sort of unaryop, but got %R", obj); - return 1; -} - -int -obj2ast_cmpop(struct ast_state *state, PyObject* obj, cmpop_ty* out, PyArena* - arena) -{ - int isinstance; - - isinstance = PyObject_IsInstance(obj, state->Eq_type); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - *out = Eq; - return 0; - } - isinstance = PyObject_IsInstance(obj, state->NotEq_type); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - *out = NotEq; - return 0; - } - isinstance = PyObject_IsInstance(obj, state->Lt_type); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - *out = Lt; - return 0; - } - isinstance = PyObject_IsInstance(obj, state->LtE_type); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - *out = LtE; - return 0; - } - isinstance = PyObject_IsInstance(obj, state->Gt_type); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - *out = Gt; - return 0; - } - isinstance = PyObject_IsInstance(obj, state->GtE_type); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - *out = GtE; - return 0; - } - isinstance = PyObject_IsInstance(obj, state->Is_type); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - *out = Is; - return 0; - } - isinstance = PyObject_IsInstance(obj, state->IsNot_type); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - *out = IsNot; - return 0; - } - isinstance = PyObject_IsInstance(obj, state->In_type); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - *out = In; - return 0; - } - isinstance = PyObject_IsInstance(obj, state->NotIn_type); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - *out = NotIn; - return 0; - } - - PyErr_Format(PyExc_TypeError, "expected some sort of cmpop, but got %R", obj); - return 1; -} - -int -obj2ast_comprehension(struct ast_state *state, PyObject* obj, comprehension_ty* - out, PyArena* arena) -{ - PyObject* tmp = NULL; - expr_ty target; - expr_ty iter; - asdl_expr_seq* ifs; - int is_async; - - if (_PyObject_LookupAttr(obj, state->target, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"target\" missing from comprehension"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'comprehension' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp, &target, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->iter, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"iter\" missing from comprehension"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'comprehension' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp, &iter, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->ifs, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"ifs\" missing from comprehension"); - return 1; - } - else { - int res; - Py_ssize_t len; - Py_ssize_t i; - if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "comprehension field \"ifs\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); - goto failed; - } - len = PyList_GET_SIZE(tmp); - ifs = _Py_asdl_expr_seq_new(len, arena); - if (ifs == NULL) goto failed; - for (i = 0; i < len; i++) { - expr_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'comprehension' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); - Py_DECREF(tmp2); - if (res != 0) goto failed; - if (len != PyList_GET_SIZE(tmp)) { - PyErr_SetString(PyExc_RuntimeError, "comprehension field \"ifs\" changed size during iteration"); - goto failed; - } - asdl_seq_SET(ifs, i, val); - } - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->is_async, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"is_async\" missing from comprehension"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'comprehension' node")) { - goto failed; - } - res = obj2ast_int(state, tmp, &is_async, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - *out = _PyAST_comprehension(target, iter, ifs, is_async, arena); - return 0; -failed: - Py_XDECREF(tmp); - return 1; -} - -int -obj2ast_excepthandler(struct ast_state *state, PyObject* obj, excepthandler_ty* - out, PyArena* arena) -{ - int isinstance; - - PyObject *tmp = NULL; - PyObject *tp; - int lineno; - int col_offset; - int end_lineno; - int end_col_offset; - - if (obj == Py_None) { - *out = NULL; - return 0; - } - if (_PyObject_LookupAttr(obj, state->lineno, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"lineno\" missing from excepthandler"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'excepthandler' node")) { - goto failed; - } - res = obj2ast_int(state, tmp, &lineno, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->col_offset, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"col_offset\" missing from excepthandler"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'excepthandler' node")) { - goto failed; - } - res = obj2ast_int(state, tmp, &col_offset, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->end_lineno, &tmp) < 0) { - return 1; - } - if (tmp == NULL || tmp == Py_None) { - Py_CLEAR(tmp); - end_lineno = 0; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'excepthandler' node")) { - goto failed; - } - res = obj2ast_int(state, tmp, &end_lineno, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->end_col_offset, &tmp) < 0) { - return 1; - } - if (tmp == NULL || tmp == Py_None) { - Py_CLEAR(tmp); - end_col_offset = 0; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'excepthandler' node")) { - goto failed; - } - res = obj2ast_int(state, tmp, &end_col_offset, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - tp = state->ExceptHandler_type; - isinstance = PyObject_IsInstance(obj, tp); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - expr_ty type; - identifier name; - asdl_stmt_seq* body; - - if (_PyObject_LookupAttr(obj, state->type, &tmp) < 0) { - return 1; - } - if (tmp == NULL || tmp == Py_None) { - Py_CLEAR(tmp); - type = NULL; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'ExceptHandler' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp, &type, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->name, &tmp) < 0) { - return 1; - } - if (tmp == NULL || tmp == Py_None) { - Py_CLEAR(tmp); - name = NULL; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'ExceptHandler' node")) { - goto failed; - } - res = obj2ast_identifier(state, tmp, &name, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->body, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from ExceptHandler"); - return 1; - } - else { - int res; - Py_ssize_t len; - Py_ssize_t i; - if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "ExceptHandler field \"body\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); - goto failed; - } - len = PyList_GET_SIZE(tmp); - body = _Py_asdl_stmt_seq_new(len, arena); - if (body == NULL) goto failed; - for (i = 0; i < len; i++) { - stmt_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'ExceptHandler' node")) { - goto failed; - } - res = obj2ast_stmt(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); - Py_DECREF(tmp2); - if (res != 0) goto failed; - if (len != PyList_GET_SIZE(tmp)) { - PyErr_SetString(PyExc_RuntimeError, "ExceptHandler field \"body\" changed size during iteration"); - goto failed; - } - asdl_seq_SET(body, i, val); - } - Py_CLEAR(tmp); - } - *out = _PyAST_ExceptHandler(type, name, body, lineno, col_offset, - end_lineno, end_col_offset, arena); - if (*out == NULL) goto failed; - return 0; - } - - PyErr_Format(PyExc_TypeError, "expected some sort of excepthandler, but got %R", obj); - failed: - Py_XDECREF(tmp); - return 1; -} - -int -obj2ast_arguments(struct ast_state *state, PyObject* obj, arguments_ty* out, - PyArena* arena) -{ - PyObject* tmp = NULL; - asdl_arg_seq* posonlyargs; - asdl_arg_seq* args; - arg_ty vararg; - asdl_arg_seq* kwonlyargs; - asdl_expr_seq* kw_defaults; - arg_ty kwarg; - asdl_expr_seq* defaults; - - if (_PyObject_LookupAttr(obj, state->posonlyargs, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"posonlyargs\" missing from arguments"); - return 1; - } - else { - int res; - Py_ssize_t len; - Py_ssize_t i; - if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "arguments field \"posonlyargs\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); - goto failed; - } - len = PyList_GET_SIZE(tmp); - posonlyargs = _Py_asdl_arg_seq_new(len, arena); - if (posonlyargs == NULL) goto failed; - for (i = 0; i < len; i++) { - arg_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'arguments' node")) { - goto failed; - } - res = obj2ast_arg(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); - Py_DECREF(tmp2); - if (res != 0) goto failed; - if (len != PyList_GET_SIZE(tmp)) { - PyErr_SetString(PyExc_RuntimeError, "arguments field \"posonlyargs\" changed size during iteration"); - goto failed; - } - asdl_seq_SET(posonlyargs, i, val); - } - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->args, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"args\" missing from arguments"); - return 1; - } - else { - int res; - Py_ssize_t len; - Py_ssize_t i; - if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "arguments field \"args\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); - goto failed; - } - len = PyList_GET_SIZE(tmp); - args = _Py_asdl_arg_seq_new(len, arena); - if (args == NULL) goto failed; - for (i = 0; i < len; i++) { - arg_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'arguments' node")) { - goto failed; - } - res = obj2ast_arg(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); - Py_DECREF(tmp2); - if (res != 0) goto failed; - if (len != PyList_GET_SIZE(tmp)) { - PyErr_SetString(PyExc_RuntimeError, "arguments field \"args\" changed size during iteration"); - goto failed; - } - asdl_seq_SET(args, i, val); - } - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->vararg, &tmp) < 0) { - return 1; - } - if (tmp == NULL || tmp == Py_None) { - Py_CLEAR(tmp); - vararg = NULL; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'arguments' node")) { - goto failed; - } - res = obj2ast_arg(state, tmp, &vararg, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->kwonlyargs, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"kwonlyargs\" missing from arguments"); - return 1; - } - else { - int res; - Py_ssize_t len; - Py_ssize_t i; - if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "arguments field \"kwonlyargs\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); - goto failed; - } - len = PyList_GET_SIZE(tmp); - kwonlyargs = _Py_asdl_arg_seq_new(len, arena); - if (kwonlyargs == NULL) goto failed; - for (i = 0; i < len; i++) { - arg_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'arguments' node")) { - goto failed; - } - res = obj2ast_arg(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); - Py_DECREF(tmp2); - if (res != 0) goto failed; - if (len != PyList_GET_SIZE(tmp)) { - PyErr_SetString(PyExc_RuntimeError, "arguments field \"kwonlyargs\" changed size during iteration"); - goto failed; - } - asdl_seq_SET(kwonlyargs, i, val); - } - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->kw_defaults, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"kw_defaults\" missing from arguments"); - return 1; - } - else { - int res; - Py_ssize_t len; - Py_ssize_t i; - if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "arguments field \"kw_defaults\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); - goto failed; - } - len = PyList_GET_SIZE(tmp); - kw_defaults = _Py_asdl_expr_seq_new(len, arena); - if (kw_defaults == NULL) goto failed; - for (i = 0; i < len; i++) { - expr_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'arguments' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); - Py_DECREF(tmp2); - if (res != 0) goto failed; - if (len != PyList_GET_SIZE(tmp)) { - PyErr_SetString(PyExc_RuntimeError, "arguments field \"kw_defaults\" changed size during iteration"); - goto failed; - } - asdl_seq_SET(kw_defaults, i, val); - } - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->kwarg, &tmp) < 0) { - return 1; - } - if (tmp == NULL || tmp == Py_None) { - Py_CLEAR(tmp); - kwarg = NULL; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'arguments' node")) { - goto failed; - } - res = obj2ast_arg(state, tmp, &kwarg, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->defaults, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"defaults\" missing from arguments"); - return 1; - } - else { - int res; - Py_ssize_t len; - Py_ssize_t i; - if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "arguments field \"defaults\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); - goto failed; - } - len = PyList_GET_SIZE(tmp); - defaults = _Py_asdl_expr_seq_new(len, arena); - if (defaults == NULL) goto failed; - for (i = 0; i < len; i++) { - expr_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'arguments' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); - Py_DECREF(tmp2); - if (res != 0) goto failed; - if (len != PyList_GET_SIZE(tmp)) { - PyErr_SetString(PyExc_RuntimeError, "arguments field \"defaults\" changed size during iteration"); - goto failed; - } - asdl_seq_SET(defaults, i, val); - } - Py_CLEAR(tmp); - } - *out = _PyAST_arguments(posonlyargs, args, vararg, kwonlyargs, kw_defaults, - kwarg, defaults, arena); - return 0; -failed: - Py_XDECREF(tmp); - return 1; -} - -int -obj2ast_arg(struct ast_state *state, PyObject* obj, arg_ty* out, PyArena* arena) -{ - PyObject* tmp = NULL; - identifier arg; - expr_ty annotation; - string type_comment; - int lineno; - int col_offset; - int end_lineno; - int end_col_offset; - - if (_PyObject_LookupAttr(obj, state->arg, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"arg\" missing from arg"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'arg' node")) { - goto failed; - } - res = obj2ast_identifier(state, tmp, &arg, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->annotation, &tmp) < 0) { - return 1; - } - if (tmp == NULL || tmp == Py_None) { - Py_CLEAR(tmp); - annotation = NULL; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'arg' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp, &annotation, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->type_comment, &tmp) < 0) { - return 1; - } - if (tmp == NULL || tmp == Py_None) { - Py_CLEAR(tmp); - type_comment = NULL; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'arg' node")) { - goto failed; - } - res = obj2ast_string(state, tmp, &type_comment, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->lineno, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"lineno\" missing from arg"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'arg' node")) { - goto failed; - } - res = obj2ast_int(state, tmp, &lineno, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->col_offset, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"col_offset\" missing from arg"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'arg' node")) { - goto failed; - } - res = obj2ast_int(state, tmp, &col_offset, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->end_lineno, &tmp) < 0) { - return 1; - } - if (tmp == NULL || tmp == Py_None) { - Py_CLEAR(tmp); - end_lineno = 0; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'arg' node")) { - goto failed; - } - res = obj2ast_int(state, tmp, &end_lineno, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->end_col_offset, &tmp) < 0) { - return 1; - } - if (tmp == NULL || tmp == Py_None) { - Py_CLEAR(tmp); - end_col_offset = 0; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'arg' node")) { - goto failed; - } - res = obj2ast_int(state, tmp, &end_col_offset, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - *out = _PyAST_arg(arg, annotation, type_comment, lineno, col_offset, - end_lineno, end_col_offset, arena); - return 0; -failed: - Py_XDECREF(tmp); - return 1; -} - -int -obj2ast_keyword(struct ast_state *state, PyObject* obj, keyword_ty* out, - PyArena* arena) -{ - PyObject* tmp = NULL; - identifier arg; - expr_ty value; - int lineno; - int col_offset; - int end_lineno; - int end_col_offset; - - if (_PyObject_LookupAttr(obj, state->arg, &tmp) < 0) { - return 1; - } - if (tmp == NULL || tmp == Py_None) { - Py_CLEAR(tmp); - arg = NULL; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'keyword' node")) { - goto failed; - } - res = obj2ast_identifier(state, tmp, &arg, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->value, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from keyword"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'keyword' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp, &value, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->lineno, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"lineno\" missing from keyword"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'keyword' node")) { - goto failed; - } - res = obj2ast_int(state, tmp, &lineno, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->col_offset, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"col_offset\" missing from keyword"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'keyword' node")) { - goto failed; - } - res = obj2ast_int(state, tmp, &col_offset, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->end_lineno, &tmp) < 0) { - return 1; - } - if (tmp == NULL || tmp == Py_None) { - Py_CLEAR(tmp); - end_lineno = 0; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'keyword' node")) { - goto failed; - } - res = obj2ast_int(state, tmp, &end_lineno, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->end_col_offset, &tmp) < 0) { - return 1; - } - if (tmp == NULL || tmp == Py_None) { - Py_CLEAR(tmp); - end_col_offset = 0; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'keyword' node")) { - goto failed; - } - res = obj2ast_int(state, tmp, &end_col_offset, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - *out = _PyAST_keyword(arg, value, lineno, col_offset, end_lineno, - end_col_offset, arena); - return 0; -failed: - Py_XDECREF(tmp); - return 1; -} - -int -obj2ast_alias(struct ast_state *state, PyObject* obj, alias_ty* out, PyArena* - arena) -{ - PyObject* tmp = NULL; - identifier name; - identifier asname; - int lineno; - int col_offset; - int end_lineno; - int end_col_offset; - - if (_PyObject_LookupAttr(obj, state->name, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"name\" missing from alias"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'alias' node")) { - goto failed; - } - res = obj2ast_identifier(state, tmp, &name, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->asname, &tmp) < 0) { - return 1; - } - if (tmp == NULL || tmp == Py_None) { - Py_CLEAR(tmp); - asname = NULL; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'alias' node")) { - goto failed; - } - res = obj2ast_identifier(state, tmp, &asname, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->lineno, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"lineno\" missing from alias"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'alias' node")) { - goto failed; - } - res = obj2ast_int(state, tmp, &lineno, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->col_offset, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"col_offset\" missing from alias"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'alias' node")) { - goto failed; - } - res = obj2ast_int(state, tmp, &col_offset, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->end_lineno, &tmp) < 0) { - return 1; - } - if (tmp == NULL || tmp == Py_None) { - Py_CLEAR(tmp); - end_lineno = 0; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'alias' node")) { - goto failed; - } - res = obj2ast_int(state, tmp, &end_lineno, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->end_col_offset, &tmp) < 0) { - return 1; - } - if (tmp == NULL || tmp == Py_None) { - Py_CLEAR(tmp); - end_col_offset = 0; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'alias' node")) { - goto failed; - } - res = obj2ast_int(state, tmp, &end_col_offset, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - *out = _PyAST_alias(name, asname, lineno, col_offset, end_lineno, - end_col_offset, arena); - return 0; -failed: - Py_XDECREF(tmp); - return 1; -} - -int -obj2ast_withitem(struct ast_state *state, PyObject* obj, withitem_ty* out, - PyArena* arena) -{ - PyObject* tmp = NULL; - expr_ty context_expr; - expr_ty optional_vars; - - if (_PyObject_LookupAttr(obj, state->context_expr, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"context_expr\" missing from withitem"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'withitem' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp, &context_expr, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->optional_vars, &tmp) < 0) { - return 1; - } - if (tmp == NULL || tmp == Py_None) { - Py_CLEAR(tmp); - optional_vars = NULL; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'withitem' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp, &optional_vars, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - *out = _PyAST_withitem(context_expr, optional_vars, arena); - return 0; -failed: - Py_XDECREF(tmp); - return 1; -} - -int -obj2ast_match_case(struct ast_state *state, PyObject* obj, match_case_ty* out, - PyArena* arena) -{ - PyObject* tmp = NULL; - pattern_ty pattern; - expr_ty guard; - asdl_stmt_seq* body; - - if (_PyObject_LookupAttr(obj, state->pattern, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"pattern\" missing from match_case"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'match_case' node")) { - goto failed; - } - res = obj2ast_pattern(state, tmp, &pattern, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->guard, &tmp) < 0) { - return 1; - } - if (tmp == NULL || tmp == Py_None) { - Py_CLEAR(tmp); - guard = NULL; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'match_case' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp, &guard, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->body, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from match_case"); - return 1; - } - else { - int res; - Py_ssize_t len; - Py_ssize_t i; - if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "match_case field \"body\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); - goto failed; - } - len = PyList_GET_SIZE(tmp); - body = _Py_asdl_stmt_seq_new(len, arena); - if (body == NULL) goto failed; - for (i = 0; i < len; i++) { - stmt_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'match_case' node")) { - goto failed; - } - res = obj2ast_stmt(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); - Py_DECREF(tmp2); - if (res != 0) goto failed; - if (len != PyList_GET_SIZE(tmp)) { - PyErr_SetString(PyExc_RuntimeError, "match_case field \"body\" changed size during iteration"); - goto failed; - } - asdl_seq_SET(body, i, val); - } - Py_CLEAR(tmp); - } - *out = _PyAST_match_case(pattern, guard, body, arena); - return 0; -failed: - Py_XDECREF(tmp); - return 1; -} - -int -obj2ast_pattern(struct ast_state *state, PyObject* obj, pattern_ty* out, - PyArena* arena) -{ - int isinstance; - - PyObject *tmp = NULL; - PyObject *tp; - int lineno; - int col_offset; - int end_lineno; - int end_col_offset; - - if (obj == Py_None) { - *out = NULL; - return 0; - } - if (_PyObject_LookupAttr(obj, state->lineno, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"lineno\" missing from pattern"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'pattern' node")) { - goto failed; - } - res = obj2ast_int(state, tmp, &lineno, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->col_offset, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"col_offset\" missing from pattern"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'pattern' node")) { - goto failed; - } - res = obj2ast_int(state, tmp, &col_offset, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->end_lineno, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"end_lineno\" missing from pattern"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'pattern' node")) { - goto failed; - } - res = obj2ast_int(state, tmp, &end_lineno, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->end_col_offset, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"end_col_offset\" missing from pattern"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'pattern' node")) { - goto failed; - } - res = obj2ast_int(state, tmp, &end_col_offset, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - tp = state->MatchValue_type; - isinstance = PyObject_IsInstance(obj, tp); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - expr_ty value; - - if (_PyObject_LookupAttr(obj, state->value, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from MatchValue"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'MatchValue' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp, &value, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - *out = _PyAST_MatchValue(value, lineno, col_offset, end_lineno, - end_col_offset, arena); - if (*out == NULL) goto failed; - return 0; - } - tp = state->MatchSingleton_type; - isinstance = PyObject_IsInstance(obj, tp); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - constant value; - - if (_PyObject_LookupAttr(obj, state->value, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from MatchSingleton"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'MatchSingleton' node")) { - goto failed; - } - res = obj2ast_constant(state, tmp, &value, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - *out = _PyAST_MatchSingleton(value, lineno, col_offset, end_lineno, - end_col_offset, arena); - if (*out == NULL) goto failed; - return 0; - } - tp = state->MatchSequence_type; - isinstance = PyObject_IsInstance(obj, tp); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - asdl_pattern_seq* patterns; - - if (_PyObject_LookupAttr(obj, state->patterns, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"patterns\" missing from MatchSequence"); - return 1; - } - else { - int res; - Py_ssize_t len; - Py_ssize_t i; - if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "MatchSequence field \"patterns\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); - goto failed; - } - len = PyList_GET_SIZE(tmp); - patterns = _Py_asdl_pattern_seq_new(len, arena); - if (patterns == NULL) goto failed; - for (i = 0; i < len; i++) { - pattern_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'MatchSequence' node")) { - goto failed; - } - res = obj2ast_pattern(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); - Py_DECREF(tmp2); - if (res != 0) goto failed; - if (len != PyList_GET_SIZE(tmp)) { - PyErr_SetString(PyExc_RuntimeError, "MatchSequence field \"patterns\" changed size during iteration"); - goto failed; - } - asdl_seq_SET(patterns, i, val); - } - Py_CLEAR(tmp); - } - *out = _PyAST_MatchSequence(patterns, lineno, col_offset, end_lineno, - end_col_offset, arena); - if (*out == NULL) goto failed; - return 0; - } - tp = state->MatchMapping_type; - isinstance = PyObject_IsInstance(obj, tp); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - asdl_expr_seq* keys; - asdl_pattern_seq* patterns; - identifier rest; - - if (_PyObject_LookupAttr(obj, state->keys, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"keys\" missing from MatchMapping"); - return 1; - } - else { - int res; - Py_ssize_t len; - Py_ssize_t i; - if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "MatchMapping field \"keys\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); - goto failed; - } - len = PyList_GET_SIZE(tmp); - keys = _Py_asdl_expr_seq_new(len, arena); - if (keys == NULL) goto failed; - for (i = 0; i < len; i++) { - expr_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'MatchMapping' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); - Py_DECREF(tmp2); - if (res != 0) goto failed; - if (len != PyList_GET_SIZE(tmp)) { - PyErr_SetString(PyExc_RuntimeError, "MatchMapping field \"keys\" changed size during iteration"); - goto failed; - } - asdl_seq_SET(keys, i, val); - } - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->patterns, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"patterns\" missing from MatchMapping"); - return 1; - } - else { - int res; - Py_ssize_t len; - Py_ssize_t i; - if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "MatchMapping field \"patterns\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); - goto failed; - } - len = PyList_GET_SIZE(tmp); - patterns = _Py_asdl_pattern_seq_new(len, arena); - if (patterns == NULL) goto failed; - for (i = 0; i < len; i++) { - pattern_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'MatchMapping' node")) { - goto failed; - } - res = obj2ast_pattern(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); - Py_DECREF(tmp2); - if (res != 0) goto failed; - if (len != PyList_GET_SIZE(tmp)) { - PyErr_SetString(PyExc_RuntimeError, "MatchMapping field \"patterns\" changed size during iteration"); - goto failed; - } - asdl_seq_SET(patterns, i, val); - } - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->rest, &tmp) < 0) { - return 1; - } - if (tmp == NULL || tmp == Py_None) { - Py_CLEAR(tmp); - rest = NULL; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'MatchMapping' node")) { - goto failed; - } - res = obj2ast_identifier(state, tmp, &rest, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - *out = _PyAST_MatchMapping(keys, patterns, rest, lineno, col_offset, - end_lineno, end_col_offset, arena); - if (*out == NULL) goto failed; - return 0; - } - tp = state->MatchClass_type; - isinstance = PyObject_IsInstance(obj, tp); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - expr_ty cls; - asdl_pattern_seq* patterns; - asdl_identifier_seq* kwd_attrs; - asdl_pattern_seq* kwd_patterns; - - if (_PyObject_LookupAttr(obj, state->cls, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"cls\" missing from MatchClass"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'MatchClass' node")) { - goto failed; - } - res = obj2ast_expr(state, tmp, &cls, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->patterns, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"patterns\" missing from MatchClass"); - return 1; - } - else { - int res; - Py_ssize_t len; - Py_ssize_t i; - if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "MatchClass field \"patterns\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); - goto failed; - } - len = PyList_GET_SIZE(tmp); - patterns = _Py_asdl_pattern_seq_new(len, arena); - if (patterns == NULL) goto failed; - for (i = 0; i < len; i++) { - pattern_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'MatchClass' node")) { - goto failed; - } - res = obj2ast_pattern(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); - Py_DECREF(tmp2); - if (res != 0) goto failed; - if (len != PyList_GET_SIZE(tmp)) { - PyErr_SetString(PyExc_RuntimeError, "MatchClass field \"patterns\" changed size during iteration"); - goto failed; - } - asdl_seq_SET(patterns, i, val); - } - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->kwd_attrs, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"kwd_attrs\" missing from MatchClass"); - return 1; - } - else { - int res; - Py_ssize_t len; - Py_ssize_t i; - if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "MatchClass field \"kwd_attrs\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); - goto failed; - } - len = PyList_GET_SIZE(tmp); - kwd_attrs = _Py_asdl_identifier_seq_new(len, arena); - if (kwd_attrs == NULL) goto failed; - for (i = 0; i < len; i++) { - identifier val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'MatchClass' node")) { - goto failed; - } - res = obj2ast_identifier(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); - Py_DECREF(tmp2); - if (res != 0) goto failed; - if (len != PyList_GET_SIZE(tmp)) { - PyErr_SetString(PyExc_RuntimeError, "MatchClass field \"kwd_attrs\" changed size during iteration"); - goto failed; - } - asdl_seq_SET(kwd_attrs, i, val); - } - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->kwd_patterns, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"kwd_patterns\" missing from MatchClass"); - return 1; - } - else { - int res; - Py_ssize_t len; - Py_ssize_t i; - if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "MatchClass field \"kwd_patterns\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); - goto failed; - } - len = PyList_GET_SIZE(tmp); - kwd_patterns = _Py_asdl_pattern_seq_new(len, arena); - if (kwd_patterns == NULL) goto failed; - for (i = 0; i < len; i++) { - pattern_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'MatchClass' node")) { - goto failed; - } - res = obj2ast_pattern(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); - Py_DECREF(tmp2); - if (res != 0) goto failed; - if (len != PyList_GET_SIZE(tmp)) { - PyErr_SetString(PyExc_RuntimeError, "MatchClass field \"kwd_patterns\" changed size during iteration"); - goto failed; - } - asdl_seq_SET(kwd_patterns, i, val); - } - Py_CLEAR(tmp); - } - *out = _PyAST_MatchClass(cls, patterns, kwd_attrs, kwd_patterns, - lineno, col_offset, end_lineno, - end_col_offset, arena); - if (*out == NULL) goto failed; - return 0; - } - tp = state->MatchStar_type; - isinstance = PyObject_IsInstance(obj, tp); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - identifier name; - - if (_PyObject_LookupAttr(obj, state->name, &tmp) < 0) { - return 1; - } - if (tmp == NULL || tmp == Py_None) { - Py_CLEAR(tmp); - name = NULL; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'MatchStar' node")) { - goto failed; - } - res = obj2ast_identifier(state, tmp, &name, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - *out = _PyAST_MatchStar(name, lineno, col_offset, end_lineno, - end_col_offset, arena); - if (*out == NULL) goto failed; - return 0; - } - tp = state->MatchAs_type; - isinstance = PyObject_IsInstance(obj, tp); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - pattern_ty pattern; - identifier name; - - if (_PyObject_LookupAttr(obj, state->pattern, &tmp) < 0) { - return 1; - } - if (tmp == NULL || tmp == Py_None) { - Py_CLEAR(tmp); - pattern = NULL; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'MatchAs' node")) { - goto failed; - } - res = obj2ast_pattern(state, tmp, &pattern, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->name, &tmp) < 0) { - return 1; - } - if (tmp == NULL || tmp == Py_None) { - Py_CLEAR(tmp); - name = NULL; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'MatchAs' node")) { - goto failed; - } - res = obj2ast_identifier(state, tmp, &name, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - *out = _PyAST_MatchAs(pattern, name, lineno, col_offset, end_lineno, - end_col_offset, arena); - if (*out == NULL) goto failed; - return 0; - } - tp = state->MatchOr_type; - isinstance = PyObject_IsInstance(obj, tp); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - asdl_pattern_seq* patterns; - - if (_PyObject_LookupAttr(obj, state->patterns, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"patterns\" missing from MatchOr"); - return 1; - } - else { - int res; - Py_ssize_t len; - Py_ssize_t i; - if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "MatchOr field \"patterns\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); - goto failed; - } - len = PyList_GET_SIZE(tmp); - patterns = _Py_asdl_pattern_seq_new(len, arena); - if (patterns == NULL) goto failed; - for (i = 0; i < len; i++) { - pattern_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'MatchOr' node")) { - goto failed; - } - res = obj2ast_pattern(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); - Py_DECREF(tmp2); - if (res != 0) goto failed; - if (len != PyList_GET_SIZE(tmp)) { - PyErr_SetString(PyExc_RuntimeError, "MatchOr field \"patterns\" changed size during iteration"); - goto failed; - } - asdl_seq_SET(patterns, i, val); - } - Py_CLEAR(tmp); - } - *out = _PyAST_MatchOr(patterns, lineno, col_offset, end_lineno, - end_col_offset, arena); - if (*out == NULL) goto failed; - return 0; - } - - PyErr_Format(PyExc_TypeError, "expected some sort of pattern, but got %R", obj); - failed: - Py_XDECREF(tmp); - return 1; -} - -int -obj2ast_type_ignore(struct ast_state *state, PyObject* obj, type_ignore_ty* - out, PyArena* arena) -{ - int isinstance; - - PyObject *tmp = NULL; - PyObject *tp; - - if (obj == Py_None) { - *out = NULL; - return 0; - } - tp = state->TypeIgnore_type; - isinstance = PyObject_IsInstance(obj, tp); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - int lineno; - string tag; - - if (_PyObject_LookupAttr(obj, state->lineno, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"lineno\" missing from TypeIgnore"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'TypeIgnore' node")) { - goto failed; - } - res = obj2ast_int(state, tmp, &lineno, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - if (_PyObject_LookupAttr(obj, state->tag, &tmp) < 0) { - return 1; - } - if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"tag\" missing from TypeIgnore"); - return 1; - } - else { - int res; - if (Py_EnterRecursiveCall(" while traversing 'TypeIgnore' node")) { - goto failed; - } - res = obj2ast_string(state, tmp, &tag, arena); - Py_LeaveRecursiveCall(); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - *out = _PyAST_TypeIgnore(lineno, tag, arena); - if (*out == NULL) goto failed; - return 0; - } - - PyErr_Format(PyExc_TypeError, "expected some sort of type_ignore, but got %R", obj); - failed: - Py_XDECREF(tmp); - return 1; -} - - -static int -astmodule_exec(PyObject *m) -{ - struct ast_state *state = get_ast_state(); - if (state == NULL) { - return -1; - } - if (PyModule_AddObjectRef(m, "AST", state->AST_type) < 0) { - return -1; - } - if (PyModule_AddIntMacro(m, PyCF_ALLOW_TOP_LEVEL_AWAIT) < 0) { - return -1; - } - if (PyModule_AddIntMacro(m, PyCF_ONLY_AST) < 0) { - return -1; - } - if (PyModule_AddIntMacro(m, PyCF_TYPE_COMMENTS) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "mod", state->mod_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "Module", state->Module_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "Interactive", state->Interactive_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "Expression", state->Expression_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "FunctionType", state->FunctionType_type) < 0) - { - return -1; - } - if (PyModule_AddObjectRef(m, "stmt", state->stmt_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "FunctionDef", state->FunctionDef_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "AsyncFunctionDef", - state->AsyncFunctionDef_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "ClassDef", state->ClassDef_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "Return", state->Return_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "Delete", state->Delete_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "Assign", state->Assign_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "AugAssign", state->AugAssign_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "AnnAssign", state->AnnAssign_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "For", state->For_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "AsyncFor", state->AsyncFor_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "While", state->While_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "If", state->If_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "With", state->With_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "AsyncWith", state->AsyncWith_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "Match", state->Match_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "Raise", state->Raise_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "Try", state->Try_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "Assert", state->Assert_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "Import", state->Import_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "ImportFrom", state->ImportFrom_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "Global", state->Global_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "Nonlocal", state->Nonlocal_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "Expr", state->Expr_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "Pass", state->Pass_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "Break", state->Break_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "Continue", state->Continue_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "expr", state->expr_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "BoolOp", state->BoolOp_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "NamedExpr", state->NamedExpr_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "BinOp", state->BinOp_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "UnaryOp", state->UnaryOp_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "Lambda", state->Lambda_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "IfExp", state->IfExp_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "Dict", state->Dict_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "Set", state->Set_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "ListComp", state->ListComp_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "SetComp", state->SetComp_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "DictComp", state->DictComp_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "GeneratorExp", state->GeneratorExp_type) < 0) - { - return -1; - } - if (PyModule_AddObjectRef(m, "Await", state->Await_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "Yield", state->Yield_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "YieldFrom", state->YieldFrom_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "Compare", state->Compare_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "Call", state->Call_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "FormattedValue", state->FormattedValue_type) - < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "JoinedStr", state->JoinedStr_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "Constant", state->Constant_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "Attribute", state->Attribute_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "Subscript", state->Subscript_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "Starred", state->Starred_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "Name", state->Name_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "List", state->List_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "Tuple", state->Tuple_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "Slice", state->Slice_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "expr_context", state->expr_context_type) < 0) - { - return -1; - } - if (PyModule_AddObjectRef(m, "Load", state->Load_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "Store", state->Store_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "Del", state->Del_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "boolop", state->boolop_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "And", state->And_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "Or", state->Or_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "operator", state->operator_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "Add", state->Add_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "Sub", state->Sub_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "Mult", state->Mult_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "MatMult", state->MatMult_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "Div", state->Div_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "Mod", state->Mod_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "Pow", state->Pow_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "LShift", state->LShift_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "RShift", state->RShift_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "BitOr", state->BitOr_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "BitXor", state->BitXor_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "BitAnd", state->BitAnd_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "FloorDiv", state->FloorDiv_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "unaryop", state->unaryop_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "Invert", state->Invert_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "Not", state->Not_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "UAdd", state->UAdd_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "USub", state->USub_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "cmpop", state->cmpop_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "Eq", state->Eq_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "NotEq", state->NotEq_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "Lt", state->Lt_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "LtE", state->LtE_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "Gt", state->Gt_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "GtE", state->GtE_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "Is", state->Is_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "IsNot", state->IsNot_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "In", state->In_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "NotIn", state->NotIn_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "comprehension", state->comprehension_type) < - 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "excepthandler", state->excepthandler_type) < - 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "ExceptHandler", state->ExceptHandler_type) < - 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "arguments", state->arguments_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "arg", state->arg_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "keyword", state->keyword_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "alias", state->alias_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "withitem", state->withitem_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "match_case", state->match_case_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "pattern", state->pattern_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "MatchValue", state->MatchValue_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "MatchSingleton", state->MatchSingleton_type) - < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "MatchSequence", state->MatchSequence_type) < - 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "MatchMapping", state->MatchMapping_type) < 0) - { - return -1; - } - if (PyModule_AddObjectRef(m, "MatchClass", state->MatchClass_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "MatchStar", state->MatchStar_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "MatchAs", state->MatchAs_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "MatchOr", state->MatchOr_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "type_ignore", state->type_ignore_type) < 0) { - return -1; - } - if (PyModule_AddObjectRef(m, "TypeIgnore", state->TypeIgnore_type) < 0) { - return -1; - } - return 0; -} - -static PyModuleDef_Slot astmodule_slots[] = { - {Py_mod_exec, astmodule_exec}, - {0, NULL} -}; - -static struct PyModuleDef _astmodule = { - PyModuleDef_HEAD_INIT, - .m_name = "_ast", - // The _ast module uses a per-interpreter state (PyInterpreterState.ast) - .m_size = 0, - .m_slots = astmodule_slots, -}; - -PyMODINIT_FUNC -PyInit__ast(void) -{ - return PyModuleDef_Init(&_astmodule); -} - - -PyObject* PyAST_mod2obj(mod_ty t) -{ - struct ast_state *state = get_ast_state(); - if (state == NULL) { - return NULL; - } - return ast2obj_mod(state, t); -} - -/* mode is 0 for "exec", 1 for "eval" and 2 for "single" input */ -mod_ty PyAST_obj2mod(PyObject* ast, PyArena* arena, int mode) -{ - const char * const req_name[] = {"Module", "Expression", "Interactive"}; - int isinstance; - - if (PySys_Audit("compile", "OO", ast, Py_None) < 0) { - return NULL; - } - - struct ast_state *state = get_ast_state(); - if (state == NULL) { - return NULL; - } - - PyObject *req_type[3]; - req_type[0] = state->Module_type; - req_type[1] = state->Expression_type; - req_type[2] = state->Interactive_type; - - assert(0 <= mode && mode <= 2); - - isinstance = PyObject_IsInstance(ast, req_type[mode]); - if (isinstance == -1) - return NULL; - if (!isinstance) { - PyErr_Format(PyExc_TypeError, "expected %s node, got %.400s", - req_name[mode], _PyType_Name(Py_TYPE(ast))); - return NULL; - } - - mod_ty res = NULL; - if (obj2ast_mod(state, ast, &res, arena) != 0) - return NULL; - else - return res; -} - -int PyAST_Check(PyObject* obj) -{ - struct ast_state *state = get_ast_state(); - if (state == NULL) { - return -1; - } - return PyObject_IsInstance(obj, state->AST_type); -} - - diff --git a/contrib/tools/python3/src/Python/_warnings.c b/contrib/tools/python3/src/Python/_warnings.c deleted file mode 100644 index 2c9a2a76872..00000000000 --- a/contrib/tools/python3/src/Python/_warnings.c +++ /dev/null @@ -1,1399 +0,0 @@ -#include "Python.h" -#include "pycore_initconfig.h" -#include "pycore_interp.h" // PyInterpreterState.warnings -#include "pycore_long.h" // _PyLong_GetZero() -#include "pycore_pyerrors.h" -#include "pycore_pystate.h" // _PyThreadState_GET() -#include "frameobject.h" // PyFrame_GetBack() -#include "clinic/_warnings.c.h" - -#define MODULE_NAME "_warnings" - -PyDoc_STRVAR(warnings__doc__, -MODULE_NAME " provides basic warning filtering support.\n" -"It is a helper module to speed up interpreter start-up."); - -_Py_IDENTIFIER(stderr); -#ifndef Py_DEBUG -_Py_IDENTIFIER(default); -_Py_IDENTIFIER(ignore); -#endif - - -/*************************************************************************/ - -typedef struct _warnings_runtime_state WarningsState; - -_Py_IDENTIFIER(__name__); - -/* Given a module object, get its per-module state. */ -static WarningsState * -warnings_get_state(void) -{ - PyInterpreterState *interp = _PyInterpreterState_GET(); - if (interp == NULL) { - PyErr_SetString(PyExc_RuntimeError, - "warnings_get_state: could not identify " - "current interpreter"); - return NULL; - } - return &interp->warnings; -} - -/* Clear the given warnings module state. */ -static void -warnings_clear_state(WarningsState *st) -{ - Py_CLEAR(st->filters); - Py_CLEAR(st->once_registry); - Py_CLEAR(st->default_action); -} - -#ifndef Py_DEBUG -static PyObject * -create_filter(PyObject *category, _Py_Identifier *id, const char *modname) -{ - PyObject *modname_obj = NULL; - PyObject *action_str = _PyUnicode_FromId(id); - if (action_str == NULL) { - return NULL; - } - - /* Default to "no module name" for initial filter set */ - if (modname != NULL) { - modname_obj = PyUnicode_InternFromString(modname); - if (modname_obj == NULL) { - return NULL; - } - } else { - modname_obj = Py_NewRef(Py_None); - } - - /* This assumes the line number is zero for now. */ - PyObject *filter = PyTuple_Pack(5, action_str, Py_None, - category, modname_obj, _PyLong_GetZero()); - Py_DECREF(modname_obj); - return filter; -} -#endif - -static PyObject * -init_filters(void) -{ -#ifdef Py_DEBUG - /* Py_DEBUG builds show all warnings by default */ - return PyList_New(0); -#else - /* Other builds ignore a number of warning categories by default */ - PyObject *filters = PyList_New(5); - if (filters == NULL) { - return NULL; - } - - size_t pos = 0; /* Post-incremented in each use. */ - PyList_SET_ITEM(filters, pos++, - create_filter(PyExc_DeprecationWarning, &PyId_default, "__main__")); - PyList_SET_ITEM(filters, pos++, - create_filter(PyExc_DeprecationWarning, &PyId_ignore, NULL)); - PyList_SET_ITEM(filters, pos++, - create_filter(PyExc_PendingDeprecationWarning, &PyId_ignore, NULL)); - PyList_SET_ITEM(filters, pos++, - create_filter(PyExc_ImportWarning, &PyId_ignore, NULL)); - PyList_SET_ITEM(filters, pos++, - create_filter(PyExc_ResourceWarning, &PyId_ignore, NULL)); - - for (size_t x = 0; x < pos; x++) { - if (PyList_GET_ITEM(filters, x) == NULL) { - Py_DECREF(filters); - return NULL; - } - } - return filters; -#endif -} - -/* Initialize the given warnings module state. */ -int -_PyWarnings_InitState(PyInterpreterState *interp) -{ - WarningsState *st = &interp->warnings; - - if (st->filters == NULL) { - st->filters = init_filters(); - if (st->filters == NULL) { - return -1; - } - } - - if (st->once_registry == NULL) { - st->once_registry = PyDict_New(); - if (st->once_registry == NULL) { - return -1; - } - } - - if (st->default_action == NULL) { - st->default_action = PyUnicode_FromString("default"); - if (st->default_action == NULL) { - return -1; - } - } - - st->filters_version = 0; - return 0; -} - - -/*************************************************************************/ - -static int -check_matched(PyObject *obj, PyObject *arg) -{ - PyObject *result; - _Py_IDENTIFIER(match); - int rc; - - /* A 'None' filter always matches */ - if (obj == Py_None) - return 1; - - /* An internal plain text default filter must match exactly */ - if (PyUnicode_CheckExact(obj)) { - int cmp_result = PyUnicode_Compare(obj, arg); - if (cmp_result == -1 && PyErr_Occurred()) { - return -1; - } - return !cmp_result; - } - - /* Otherwise assume a regex filter and call its match() method */ - result = _PyObject_CallMethodIdOneArg(obj, &PyId_match, arg); - if (result == NULL) - return -1; - - rc = PyObject_IsTrue(result); - Py_DECREF(result); - return rc; -} - -/* - Returns a new reference. - A NULL return value can mean false or an error. -*/ -static PyObject * -get_warnings_attr(_Py_Identifier *attr_id, int try_import) -{ - PyObject *warnings_str; - PyObject *warnings_module, *obj; - _Py_IDENTIFIER(warnings); - - warnings_str = _PyUnicode_FromId(&PyId_warnings); - if (warnings_str == NULL) { - return NULL; - } - - /* don't try to import after the start of the Python finallization */ - if (try_import && !_Py_IsFinalizing()) { - warnings_module = PyImport_Import(warnings_str); - if (warnings_module == NULL) { - /* Fallback to the C implementation if we cannot get - the Python implementation */ - if (PyErr_ExceptionMatches(PyExc_ImportError)) { - PyErr_Clear(); - } - return NULL; - } - } - else { - /* if we're so late into Python finalization that the module dict is - gone, then we can't even use PyImport_GetModule without triggering - an interpreter abort. - */ - if (!_PyInterpreterState_GET()->modules) { - return NULL; - } - warnings_module = PyImport_GetModule(warnings_str); - if (warnings_module == NULL) - return NULL; - } - - (void)_PyObject_LookupAttrId(warnings_module, attr_id, &obj); - Py_DECREF(warnings_module); - return obj; -} - - -static PyObject * -get_once_registry(WarningsState *st) -{ - PyObject *registry; - _Py_IDENTIFIER(onceregistry); - - registry = get_warnings_attr(&PyId_onceregistry, 0); - if (registry == NULL) { - if (PyErr_Occurred()) - return NULL; - assert(st->once_registry); - return st->once_registry; - } - if (!PyDict_Check(registry)) { - PyErr_Format(PyExc_TypeError, - MODULE_NAME ".onceregistry must be a dict, " - "not '%.200s'", - Py_TYPE(registry)->tp_name); - Py_DECREF(registry); - return NULL; - } - Py_SETREF(st->once_registry, registry); - return registry; -} - - -static PyObject * -get_default_action(WarningsState *st) -{ - PyObject *default_action; - _Py_IDENTIFIER(defaultaction); - - default_action = get_warnings_attr(&PyId_defaultaction, 0); - if (default_action == NULL) { - if (PyErr_Occurred()) { - return NULL; - } - assert(st->default_action); - return st->default_action; - } - if (!PyUnicode_Check(default_action)) { - PyErr_Format(PyExc_TypeError, - MODULE_NAME ".defaultaction must be a string, " - "not '%.200s'", - Py_TYPE(default_action)->tp_name); - Py_DECREF(default_action); - return NULL; - } - Py_SETREF(st->default_action, default_action); - return default_action; -} - - -/* The item is a new reference. */ -static PyObject* -get_filter(PyObject *category, PyObject *text, Py_ssize_t lineno, - PyObject *module, PyObject **item) -{ - PyObject *action; - Py_ssize_t i; - PyObject *warnings_filters; - _Py_IDENTIFIER(filters); - WarningsState *st = warnings_get_state(); - if (st == NULL) { - return NULL; - } - - warnings_filters = get_warnings_attr(&PyId_filters, 0); - if (warnings_filters == NULL) { - if (PyErr_Occurred()) - return NULL; - } - else { - Py_SETREF(st->filters, warnings_filters); - } - - PyObject *filters = st->filters; - if (filters == NULL || !PyList_Check(filters)) { - PyErr_SetString(PyExc_ValueError, - MODULE_NAME ".filters must be a list"); - return NULL; - } - - /* WarningsState.filters could change while we are iterating over it. */ - for (i = 0; i < PyList_GET_SIZE(filters); i++) { - PyObject *tmp_item, *action, *msg, *cat, *mod, *ln_obj; - Py_ssize_t ln; - int is_subclass, good_msg, good_mod; - - tmp_item = PyList_GET_ITEM(filters, i); - if (!PyTuple_Check(tmp_item) || PyTuple_GET_SIZE(tmp_item) != 5) { - PyErr_Format(PyExc_ValueError, - MODULE_NAME ".filters item %zd isn't a 5-tuple", i); - return NULL; - } - - /* Python code: action, msg, cat, mod, ln = item */ - Py_INCREF(tmp_item); - action = PyTuple_GET_ITEM(tmp_item, 0); - msg = PyTuple_GET_ITEM(tmp_item, 1); - cat = PyTuple_GET_ITEM(tmp_item, 2); - mod = PyTuple_GET_ITEM(tmp_item, 3); - ln_obj = PyTuple_GET_ITEM(tmp_item, 4); - - if (!PyUnicode_Check(action)) { - PyErr_Format(PyExc_TypeError, - "action must be a string, not '%.200s'", - Py_TYPE(action)->tp_name); - Py_DECREF(tmp_item); - return NULL; - } - - good_msg = check_matched(msg, text); - if (good_msg == -1) { - Py_DECREF(tmp_item); - return NULL; - } - - good_mod = check_matched(mod, module); - if (good_mod == -1) { - Py_DECREF(tmp_item); - return NULL; - } - - is_subclass = PyObject_IsSubclass(category, cat); - if (is_subclass == -1) { - Py_DECREF(tmp_item); - return NULL; - } - - ln = PyLong_AsSsize_t(ln_obj); - if (ln == -1 && PyErr_Occurred()) { - Py_DECREF(tmp_item); - return NULL; - } - - if (good_msg && is_subclass && good_mod && (ln == 0 || lineno == ln)) { - *item = tmp_item; - return action; - } - - Py_DECREF(tmp_item); - } - - action = get_default_action(st); - if (action != NULL) { - Py_INCREF(Py_None); - *item = Py_None; - return action; - } - - return NULL; -} - - -static int -already_warned(PyObject *registry, PyObject *key, int should_set) -{ - PyObject *version_obj, *already_warned; - _Py_IDENTIFIER(version); - - if (key == NULL) - return -1; - - WarningsState *st = warnings_get_state(); - if (st == NULL) { - return -1; - } - version_obj = _PyDict_GetItemIdWithError(registry, &PyId_version); - if (version_obj == NULL - || !PyLong_CheckExact(version_obj) - || PyLong_AsLong(version_obj) != st->filters_version) - { - if (PyErr_Occurred()) { - return -1; - } - PyDict_Clear(registry); - version_obj = PyLong_FromLong(st->filters_version); - if (version_obj == NULL) - return -1; - if (_PyDict_SetItemId(registry, &PyId_version, version_obj) < 0) { - Py_DECREF(version_obj); - return -1; - } - Py_DECREF(version_obj); - } - else { - already_warned = PyDict_GetItemWithError(registry, key); - if (already_warned != NULL) { - int rc = PyObject_IsTrue(already_warned); - if (rc != 0) - return rc; - } - else if (PyErr_Occurred()) { - return -1; - } - } - - /* This warning wasn't found in the registry, set it. */ - if (should_set) - return PyDict_SetItem(registry, key, Py_True); - return 0; -} - -/* New reference. */ -static PyObject * -normalize_module(PyObject *filename) -{ - PyObject *module; - int kind; - const void *data; - Py_ssize_t len; - - len = PyUnicode_GetLength(filename); - if (len < 0) - return NULL; - - if (len == 0) - return PyUnicode_FromString("<unknown>"); - - kind = PyUnicode_KIND(filename); - data = PyUnicode_DATA(filename); - - /* if filename.endswith(".py"): */ - if (len >= 3 && - PyUnicode_READ(kind, data, len-3) == '.' && - PyUnicode_READ(kind, data, len-2) == 'p' && - PyUnicode_READ(kind, data, len-1) == 'y') - { - module = PyUnicode_Substring(filename, 0, len-3); - } - else { - module = filename; - Py_INCREF(module); - } - return module; -} - -static int -update_registry(PyObject *registry, PyObject *text, PyObject *category, - int add_zero) -{ - PyObject *altkey; - int rc; - - if (add_zero) - altkey = PyTuple_Pack(3, text, category, _PyLong_GetZero()); - else - altkey = PyTuple_Pack(2, text, category); - - rc = already_warned(registry, altkey, 1); - Py_XDECREF(altkey); - return rc; -} - -static void -show_warning(PyObject *filename, int lineno, PyObject *text, - PyObject *category, PyObject *sourceline) -{ - PyObject *f_stderr; - PyObject *name; - char lineno_str[128]; - - PyOS_snprintf(lineno_str, sizeof(lineno_str), ":%d: ", lineno); - - name = _PyObject_GetAttrId(category, &PyId___name__); - if (name == NULL) { - goto error; - } - - f_stderr = _PySys_GetObjectId(&PyId_stderr); - if (f_stderr == NULL) { - fprintf(stderr, "lost sys.stderr\n"); - goto error; - } - - /* Print "filename:lineno: category: text\n" */ - if (PyFile_WriteObject(filename, f_stderr, Py_PRINT_RAW) < 0) - goto error; - if (PyFile_WriteString(lineno_str, f_stderr) < 0) - goto error; - if (PyFile_WriteObject(name, f_stderr, Py_PRINT_RAW) < 0) - goto error; - if (PyFile_WriteString(": ", f_stderr) < 0) - goto error; - if (PyFile_WriteObject(text, f_stderr, Py_PRINT_RAW) < 0) - goto error; - if (PyFile_WriteString("\n", f_stderr) < 0) - goto error; - Py_CLEAR(name); - - /* Print " source_line\n" */ - if (sourceline) { - int kind; - const void *data; - Py_ssize_t i, len; - Py_UCS4 ch; - PyObject *truncated; - - if (PyUnicode_READY(sourceline) < 1) - goto error; - - kind = PyUnicode_KIND(sourceline); - data = PyUnicode_DATA(sourceline); - len = PyUnicode_GET_LENGTH(sourceline); - for (i=0; i<len; i++) { - ch = PyUnicode_READ(kind, data, i); - if (ch != ' ' && ch != '\t' && ch != '\014') - break; - } - - truncated = PyUnicode_Substring(sourceline, i, len); - if (truncated == NULL) - goto error; - - PyFile_WriteObject(sourceline, f_stderr, Py_PRINT_RAW); - Py_DECREF(truncated); - PyFile_WriteString("\n", f_stderr); - } - else { - _Py_DisplaySourceLine(f_stderr, filename, lineno, 2); - } - -error: - Py_XDECREF(name); - PyErr_Clear(); -} - -static int -call_show_warning(PyObject *category, PyObject *text, PyObject *message, - PyObject *filename, int lineno, PyObject *lineno_obj, - PyObject *sourceline, PyObject *source) -{ - PyObject *show_fn, *msg, *res, *warnmsg_cls = NULL; - _Py_IDENTIFIER(_showwarnmsg); - _Py_IDENTIFIER(WarningMessage); - - /* If the source parameter is set, try to get the Python implementation. - The Python implementation is able to log the traceback where the source - was allocated, whereas the C implementation doesn't. */ - show_fn = get_warnings_attr(&PyId__showwarnmsg, source != NULL); - if (show_fn == NULL) { - if (PyErr_Occurred()) - return -1; - show_warning(filename, lineno, text, category, sourceline); - return 0; - } - - if (!PyCallable_Check(show_fn)) { - PyErr_SetString(PyExc_TypeError, - "warnings._showwarnmsg() must be set to a callable"); - goto error; - } - - warnmsg_cls = get_warnings_attr(&PyId_WarningMessage, 0); - if (warnmsg_cls == NULL) { - if (!PyErr_Occurred()) { - PyErr_SetString(PyExc_RuntimeError, - "unable to get warnings.WarningMessage"); - } - goto error; - } - - msg = PyObject_CallFunctionObjArgs(warnmsg_cls, message, category, - filename, lineno_obj, Py_None, Py_None, source, - NULL); - Py_DECREF(warnmsg_cls); - if (msg == NULL) - goto error; - - res = PyObject_CallOneArg(show_fn, msg); - Py_DECREF(show_fn); - Py_DECREF(msg); - - if (res == NULL) - return -1; - - Py_DECREF(res); - return 0; - -error: - Py_XDECREF(show_fn); - return -1; -} - -static PyObject * -warn_explicit(PyObject *category, PyObject *message, - PyObject *filename, int lineno, - PyObject *module, PyObject *registry, PyObject *sourceline, - PyObject *source) -{ - PyObject *key = NULL, *text = NULL, *result = NULL, *lineno_obj = NULL; - PyObject *item = NULL; - PyObject *action; - int rc; - - /* module can be None if a warning is emitted late during Python shutdown. - In this case, the Python warnings module was probably unloaded, filters - are no more available to choose as action. It is safer to ignore the - warning and do nothing. */ - if (module == Py_None) - Py_RETURN_NONE; - - if (registry && !PyDict_Check(registry) && (registry != Py_None)) { - PyErr_SetString(PyExc_TypeError, "'registry' must be a dict or None"); - return NULL; - } - - /* Normalize module. */ - if (module == NULL) { - module = normalize_module(filename); - if (module == NULL) - return NULL; - } - else - Py_INCREF(module); - - /* Normalize message. */ - Py_INCREF(message); /* DECREF'ed in cleanup. */ - rc = PyObject_IsInstance(message, PyExc_Warning); - if (rc == -1) { - goto cleanup; - } - if (rc == 1) { - text = PyObject_Str(message); - if (text == NULL) - goto cleanup; - category = (PyObject*)Py_TYPE(message); - } - else { - text = message; - message = PyObject_CallOneArg(category, message); - if (message == NULL) - goto cleanup; - } - - lineno_obj = PyLong_FromLong(lineno); - if (lineno_obj == NULL) - goto cleanup; - - if (source == Py_None) { - source = NULL; - } - - /* Create key. */ - key = PyTuple_Pack(3, text, category, lineno_obj); - if (key == NULL) - goto cleanup; - - if ((registry != NULL) && (registry != Py_None)) { - rc = already_warned(registry, key, 0); - if (rc == -1) - goto cleanup; - else if (rc == 1) - goto return_none; - /* Else this warning hasn't been generated before. */ - } - - action = get_filter(category, text, lineno, module, &item); - if (action == NULL) - goto cleanup; - - if (_PyUnicode_EqualToASCIIString(action, "error")) { - PyErr_SetObject(category, message); - goto cleanup; - } - - if (_PyUnicode_EqualToASCIIString(action, "ignore")) { - goto return_none; - } - - /* Store in the registry that we've been here, *except* when the action - is "always". */ - rc = 0; - if (!_PyUnicode_EqualToASCIIString(action, "always")) { - if (registry != NULL && registry != Py_None && - PyDict_SetItem(registry, key, Py_True) < 0) - { - goto cleanup; - } - - if (_PyUnicode_EqualToASCIIString(action, "once")) { - if (registry == NULL || registry == Py_None) { - WarningsState *st = warnings_get_state(); - if (st == NULL) { - goto cleanup; - } - registry = get_once_registry(st); - if (registry == NULL) - goto cleanup; - } - /* WarningsState.once_registry[(text, category)] = 1 */ - rc = update_registry(registry, text, category, 0); - } - else if (_PyUnicode_EqualToASCIIString(action, "module")) { - /* registry[(text, category, 0)] = 1 */ - if (registry != NULL && registry != Py_None) - rc = update_registry(registry, text, category, 0); - } - else if (!_PyUnicode_EqualToASCIIString(action, "default")) { - PyErr_Format(PyExc_RuntimeError, - "Unrecognized action (%R) in warnings.filters:\n %R", - action, item); - goto cleanup; - } - } - - if (rc == 1) /* Already warned for this module. */ - goto return_none; - if (rc == 0) { - if (call_show_warning(category, text, message, filename, lineno, - lineno_obj, sourceline, source) < 0) - goto cleanup; - } - else /* if (rc == -1) */ - goto cleanup; - - return_none: - result = Py_None; - Py_INCREF(result); - - cleanup: - Py_XDECREF(item); - Py_XDECREF(key); - Py_XDECREF(text); - Py_XDECREF(lineno_obj); - Py_DECREF(module); - Py_XDECREF(message); - return result; /* Py_None or NULL. */ -} - -static int -is_internal_frame(PyFrameObject *frame) -{ - static PyObject *importlib_string = NULL; - static PyObject *bootstrap_string = NULL; - int contains; - - if (importlib_string == NULL) { - importlib_string = PyUnicode_FromString("importlib"); - if (importlib_string == NULL) { - return 0; - } - - bootstrap_string = PyUnicode_FromString("_bootstrap"); - if (bootstrap_string == NULL) { - Py_DECREF(importlib_string); - return 0; - } - Py_INCREF(importlib_string); - Py_INCREF(bootstrap_string); - } - - if (frame == NULL) { - return 0; - } - - PyCodeObject *code = PyFrame_GetCode(frame); - PyObject *filename = code->co_filename; - Py_DECREF(code); - - if (filename == NULL) { - return 0; - } - if (!PyUnicode_Check(filename)) { - return 0; - } - - contains = PyUnicode_Contains(filename, importlib_string); - if (contains < 0) { - return 0; - } - else if (contains > 0) { - contains = PyUnicode_Contains(filename, bootstrap_string); - if (contains < 0) { - return 0; - } - else if (contains > 0) { - return 1; - } - } - - return 0; -} - -static PyFrameObject * -next_external_frame(PyFrameObject *frame) -{ - do { - PyFrameObject *back = PyFrame_GetBack(frame); - Py_DECREF(frame); - frame = back; - } while (frame != NULL && is_internal_frame(frame)); - - return frame; -} - -/* filename, module, and registry are new refs, globals is borrowed */ -/* Returns 0 on error (no new refs), 1 on success */ -static int -setup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno, - PyObject **module, PyObject **registry) -{ - _Py_IDENTIFIER(__warningregistry__); - PyObject *globals; - - /* Setup globals, filename and lineno. */ - PyThreadState *tstate = _PyThreadState_GET(); - PyFrameObject *f = PyThreadState_GetFrame(tstate); - // Stack level comparisons to Python code is off by one as there is no - // warnings-related stack level to avoid. - if (stack_level <= 0 || is_internal_frame(f)) { - while (--stack_level > 0 && f != NULL) { - PyFrameObject *back = PyFrame_GetBack(f); - Py_DECREF(f); - f = back; - } - } - else { - while (--stack_level > 0 && f != NULL) { - f = next_external_frame(f); - } - } - - if (f == NULL) { - globals = tstate->interp->sysdict; - *filename = PyUnicode_FromString("sys"); - *lineno = 1; - } - else { - globals = f->f_globals; - PyCodeObject *code = PyFrame_GetCode(f); - *filename = code->co_filename; - Py_DECREF(code); - Py_INCREF(*filename); - *lineno = PyFrame_GetLineNumber(f); - Py_DECREF(f); - } - - *module = NULL; - - /* Setup registry. */ - assert(globals != NULL); - assert(PyDict_Check(globals)); - *registry = _PyDict_GetItemIdWithError(globals, &PyId___warningregistry__); - if (*registry == NULL) { - int rc; - - if (_PyErr_Occurred(tstate)) { - goto handle_error; - } - *registry = PyDict_New(); - if (*registry == NULL) - goto handle_error; - - rc = _PyDict_SetItemId(globals, &PyId___warningregistry__, *registry); - if (rc < 0) - goto handle_error; - } - else - Py_INCREF(*registry); - - /* Setup module. */ - *module = _PyDict_GetItemIdWithError(globals, &PyId___name__); - if (*module == Py_None || (*module != NULL && PyUnicode_Check(*module))) { - Py_INCREF(*module); - } - else if (_PyErr_Occurred(tstate)) { - goto handle_error; - } - else { - *module = PyUnicode_FromString("<string>"); - if (*module == NULL) - goto handle_error; - } - - return 1; - - handle_error: - Py_XDECREF(*registry); - Py_XDECREF(*module); - Py_DECREF(*filename); - return 0; -} - -static PyObject * -get_category(PyObject *message, PyObject *category) -{ - int rc; - - /* Get category. */ - rc = PyObject_IsInstance(message, PyExc_Warning); - if (rc == -1) - return NULL; - - if (rc == 1) - category = (PyObject*)Py_TYPE(message); - else if (category == NULL || category == Py_None) - category = PyExc_UserWarning; - - /* Validate category. */ - rc = PyObject_IsSubclass(category, PyExc_Warning); - /* category is not a subclass of PyExc_Warning or - PyObject_IsSubclass raised an error */ - if (rc == -1 || rc == 0) { - PyErr_Format(PyExc_TypeError, - "category must be a Warning subclass, not '%s'", - Py_TYPE(category)->tp_name); - return NULL; - } - - return category; -} - -static PyObject * -do_warn(PyObject *message, PyObject *category, Py_ssize_t stack_level, - PyObject *source) -{ - PyObject *filename, *module, *registry, *res; - int lineno; - - if (!setup_context(stack_level, &filename, &lineno, &module, ®istry)) - return NULL; - - res = warn_explicit(category, message, filename, lineno, module, registry, - NULL, source); - Py_DECREF(filename); - Py_DECREF(registry); - Py_DECREF(module); - return res; -} - -/*[clinic input] -warn as warnings_warn - - message: object - category: object = None - stacklevel: Py_ssize_t = 1 - source: object = None - -Issue a warning, or maybe ignore it or raise an exception. -[clinic start generated code]*/ - -static PyObject * -warnings_warn_impl(PyObject *module, PyObject *message, PyObject *category, - Py_ssize_t stacklevel, PyObject *source) -/*[clinic end generated code: output=31ed5ab7d8d760b2 input=bfdf5cf99f6c4edd]*/ -{ - category = get_category(message, category); - if (category == NULL) - return NULL; - return do_warn(message, category, stacklevel, source); -} - -static PyObject * -get_source_line(PyObject *module_globals, int lineno) -{ - _Py_IDENTIFIER(get_source); - _Py_IDENTIFIER(__loader__); - PyObject *loader; - PyObject *module_name; - PyObject *get_source; - PyObject *source; - PyObject *source_list; - PyObject *source_line; - - /* Check/get the requisite pieces needed for the loader. */ - loader = _PyDict_GetItemIdWithError(module_globals, &PyId___loader__); - if (loader == NULL) { - return NULL; - } - Py_INCREF(loader); - module_name = _PyDict_GetItemIdWithError(module_globals, &PyId___name__); - if (!module_name) { - Py_DECREF(loader); - return NULL; - } - Py_INCREF(module_name); - - /* Make sure the loader implements the optional get_source() method. */ - (void)_PyObject_LookupAttrId(loader, &PyId_get_source, &get_source); - Py_DECREF(loader); - if (!get_source) { - Py_DECREF(module_name); - return NULL; - } - /* Call get_source() to get the source code. */ - source = PyObject_CallOneArg(get_source, module_name); - Py_DECREF(get_source); - Py_DECREF(module_name); - if (!source) { - return NULL; - } - if (source == Py_None) { - Py_DECREF(source); - return NULL; - } - - /* Split the source into lines. */ - source_list = PyUnicode_Splitlines(source, 0); - Py_DECREF(source); - if (!source_list) { - return NULL; - } - - /* Get the source line. */ - source_line = PyList_GetItem(source_list, lineno-1); - Py_XINCREF(source_line); - Py_DECREF(source_list); - return source_line; -} - -static PyObject * -warnings_warn_explicit(PyObject *self, PyObject *args, PyObject *kwds) -{ - static char *kwd_list[] = {"message", "category", "filename", "lineno", - "module", "registry", "module_globals", - "source", 0}; - PyObject *message; - PyObject *category; - PyObject *filename; - int lineno; - PyObject *module = NULL; - PyObject *registry = NULL; - PyObject *module_globals = NULL; - PyObject *sourceobj = NULL; - PyObject *source_line = NULL; - PyObject *returned; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOUi|OOOO:warn_explicit", - kwd_list, &message, &category, &filename, &lineno, &module, - ®istry, &module_globals, &sourceobj)) - return NULL; - - if (module_globals && module_globals != Py_None) { - if (!PyDict_Check(module_globals)) { - PyErr_Format(PyExc_TypeError, - "module_globals must be a dict, not '%.200s'", - Py_TYPE(module_globals)->tp_name); - return NULL; - } - - source_line = get_source_line(module_globals, lineno); - if (source_line == NULL && PyErr_Occurred()) { - return NULL; - } - } - returned = warn_explicit(category, message, filename, lineno, module, - registry, source_line, sourceobj); - Py_XDECREF(source_line); - return returned; -} - -static PyObject * -warnings_filters_mutated(PyObject *self, PyObject *args) -{ - WarningsState *st = warnings_get_state(); - if (st == NULL) { - return NULL; - } - st->filters_version++; - Py_RETURN_NONE; -} - - -/* Function to issue a warning message; may raise an exception. */ - -static int -warn_unicode(PyObject *category, PyObject *message, - Py_ssize_t stack_level, PyObject *source) -{ - PyObject *res; - - if (category == NULL) - category = PyExc_RuntimeWarning; - - res = do_warn(message, category, stack_level, source); - if (res == NULL) - return -1; - Py_DECREF(res); - - return 0; -} - -static int -_PyErr_WarnFormatV(PyObject *source, - PyObject *category, Py_ssize_t stack_level, - const char *format, va_list vargs) -{ - PyObject *message; - int res; - - message = PyUnicode_FromFormatV(format, vargs); - if (message == NULL) - return -1; - - res = warn_unicode(category, message, stack_level, source); - Py_DECREF(message); - return res; -} - -int -PyErr_WarnFormat(PyObject *category, Py_ssize_t stack_level, - const char *format, ...) -{ - int res; - va_list vargs; - -#ifdef HAVE_STDARG_PROTOTYPES - va_start(vargs, format); -#else - va_start(vargs); -#endif - res = _PyErr_WarnFormatV(NULL, category, stack_level, format, vargs); - va_end(vargs); - return res; -} - -static int -_PyErr_WarnFormat(PyObject *source, PyObject *category, Py_ssize_t stack_level, - const char *format, ...) -{ - int res; - va_list vargs; - -#ifdef HAVE_STDARG_PROTOTYPES - va_start(vargs, format); -#else - va_start(vargs); -#endif - res = _PyErr_WarnFormatV(source, category, stack_level, format, vargs); - va_end(vargs); - return res; -} - -int -PyErr_ResourceWarning(PyObject *source, Py_ssize_t stack_level, - const char *format, ...) -{ - int res; - va_list vargs; - -#ifdef HAVE_STDARG_PROTOTYPES - va_start(vargs, format); -#else - va_start(vargs); -#endif - res = _PyErr_WarnFormatV(source, PyExc_ResourceWarning, - stack_level, format, vargs); - va_end(vargs); - return res; -} - - -int -PyErr_WarnEx(PyObject *category, const char *text, Py_ssize_t stack_level) -{ - int ret; - PyObject *message = PyUnicode_FromString(text); - if (message == NULL) - return -1; - ret = warn_unicode(category, message, stack_level, NULL); - Py_DECREF(message); - return ret; -} - -/* PyErr_Warn is only for backwards compatibility and will be removed. - Use PyErr_WarnEx instead. */ - -#undef PyErr_Warn - -int -PyErr_Warn(PyObject *category, const char *text) -{ - return PyErr_WarnEx(category, text, 1); -} - -/* Warning with explicit origin */ -int -PyErr_WarnExplicitObject(PyObject *category, PyObject *message, - PyObject *filename, int lineno, - PyObject *module, PyObject *registry) -{ - PyObject *res; - if (category == NULL) - category = PyExc_RuntimeWarning; - res = warn_explicit(category, message, filename, lineno, - module, registry, NULL, NULL); - if (res == NULL) - return -1; - Py_DECREF(res); - return 0; -} - -int -PyErr_WarnExplicit(PyObject *category, const char *text, - const char *filename_str, int lineno, - const char *module_str, PyObject *registry) -{ - PyObject *message = PyUnicode_FromString(text); - PyObject *filename = PyUnicode_DecodeFSDefault(filename_str); - PyObject *module = NULL; - int ret = -1; - - if (message == NULL || filename == NULL) - goto exit; - if (module_str != NULL) { - module = PyUnicode_FromString(module_str); - if (module == NULL) - goto exit; - } - - ret = PyErr_WarnExplicitObject(category, message, filename, lineno, - module, registry); - - exit: - Py_XDECREF(message); - Py_XDECREF(module); - Py_XDECREF(filename); - return ret; -} - -int -PyErr_WarnExplicitFormat(PyObject *category, - const char *filename_str, int lineno, - const char *module_str, PyObject *registry, - const char *format, ...) -{ - PyObject *message; - PyObject *module = NULL; - PyObject *filename = PyUnicode_DecodeFSDefault(filename_str); - int ret = -1; - va_list vargs; - - if (filename == NULL) - goto exit; - if (module_str != NULL) { - module = PyUnicode_FromString(module_str); - if (module == NULL) - goto exit; - } - -#ifdef HAVE_STDARG_PROTOTYPES - va_start(vargs, format); -#else - va_start(vargs); -#endif - message = PyUnicode_FromFormatV(format, vargs); - if (message != NULL) { - PyObject *res; - res = warn_explicit(category, message, filename, lineno, - module, registry, NULL, NULL); - Py_DECREF(message); - if (res != NULL) { - Py_DECREF(res); - ret = 0; - } - } - va_end(vargs); -exit: - Py_XDECREF(module); - Py_XDECREF(filename); - return ret; -} - -void -_PyErr_WarnUnawaitedCoroutine(PyObject *coro) -{ - /* First, we attempt to funnel the warning through - warnings._warn_unawaited_coroutine. - - This could raise an exception, due to: - - a bug - - some kind of shutdown-related brokenness - - succeeding, but with an "error" warning filter installed, so the - warning is converted into a RuntimeWarning exception - - In the first two cases, we want to print the error (so we know what it - is!), and then print a warning directly as a fallback. In the last - case, we want to print the error (since it's the warning!), but *not* - do a fallback. And after we print the error we can't check for what - type of error it was (because PyErr_WriteUnraisable clears it), so we - need a flag to keep track. - - Since this is called from __del__ context, it's careful to never raise - an exception. - */ - _Py_IDENTIFIER(_warn_unawaited_coroutine); - int warned = 0; - PyObject *fn = get_warnings_attr(&PyId__warn_unawaited_coroutine, 1); - if (fn) { - PyObject *res = PyObject_CallOneArg(fn, coro); - Py_DECREF(fn); - if (res || PyErr_ExceptionMatches(PyExc_RuntimeWarning)) { - warned = 1; - } - Py_XDECREF(res); - } - - if (PyErr_Occurred()) { - PyErr_WriteUnraisable(coro); - } - if (!warned) { - if (_PyErr_WarnFormat(coro, PyExc_RuntimeWarning, 1, - "coroutine '%S' was never awaited", - ((PyCoroObject *)coro)->cr_qualname) < 0) - { - PyErr_WriteUnraisable(coro); - } - } -} - -PyDoc_STRVAR(warn_explicit_doc, -"Low-level interface to warnings functionality."); - -static PyMethodDef warnings_functions[] = { - WARNINGS_WARN_METHODDEF - {"warn_explicit", (PyCFunction)(void(*)(void))warnings_warn_explicit, - METH_VARARGS | METH_KEYWORDS, warn_explicit_doc}, - {"_filters_mutated", (PyCFunction)warnings_filters_mutated, METH_NOARGS, - NULL}, - /* XXX(brett.cannon): add showwarning? */ - /* XXX(brett.cannon): Reasonable to add formatwarning? */ - {NULL, NULL} /* sentinel */ -}; - - -static int -warnings_module_exec(PyObject *module) -{ - WarningsState *st = warnings_get_state(); - if (st == NULL) { - return -1; - } - if (PyModule_AddObjectRef(module, "filters", st->filters) < 0) { - return -1; - } - if (PyModule_AddObjectRef(module, "_onceregistry", st->once_registry) < 0) { - return -1; - } - if (PyModule_AddObjectRef(module, "_defaultaction", st->default_action) < 0) { - return -1; - } - return 0; -} - - -static PyModuleDef_Slot warnings_slots[] = { - {Py_mod_exec, warnings_module_exec}, - {0, NULL} -}; - -static struct PyModuleDef warnings_module = { - PyModuleDef_HEAD_INIT, - .m_name = MODULE_NAME, - .m_doc = warnings__doc__, - .m_size = 0, - .m_methods = warnings_functions, - .m_slots = warnings_slots, -}; - - -PyMODINIT_FUNC -_PyWarnings_Init(void) -{ - return PyModuleDef_Init(&warnings_module); -} - -// We need this to ensure that warnings still work until late in finalization. -void -_PyWarnings_Fini(PyInterpreterState *interp) -{ - warnings_clear_state(&interp->warnings); -} diff --git a/contrib/tools/python3/src/Python/asdl.c b/contrib/tools/python3/src/Python/asdl.c deleted file mode 100644 index a7f2180c88e..00000000000 --- a/contrib/tools/python3/src/Python/asdl.c +++ /dev/null @@ -1,6 +0,0 @@ -#include "Python.h" -#include "pycore_asdl.h" - -GENERATE_ASDL_SEQ_CONSTRUCTOR(generic, void*); -GENERATE_ASDL_SEQ_CONSTRUCTOR(identifier, PyObject*); -GENERATE_ASDL_SEQ_CONSTRUCTOR(int, int); diff --git a/contrib/tools/python3/src/Python/ast.c b/contrib/tools/python3/src/Python/ast.c deleted file mode 100644 index 2113124dbd5..00000000000 --- a/contrib/tools/python3/src/Python/ast.c +++ /dev/null @@ -1,989 +0,0 @@ -/* - * This file exposes PyAST_Validate interface to check the integrity - * of the given abstract syntax tree (potentially constructed manually). - */ -#include "Python.h" -#include "pycore_ast.h" // asdl_stmt_seq -#include "pycore_pystate.h" // _PyThreadState_GET() - -#include <assert.h> -#include <stdbool.h> - -struct validator { - int recursion_depth; /* current recursion depth */ - int recursion_limit; /* recursion limit */ -}; - -static int validate_stmts(struct validator *, asdl_stmt_seq *); -static int validate_exprs(struct validator *, asdl_expr_seq *, expr_context_ty, int); -static int validate_patterns(struct validator *, asdl_pattern_seq *, int); -static int _validate_nonempty_seq(asdl_seq *, const char *, const char *); -static int validate_stmt(struct validator *, stmt_ty); -static int validate_expr(struct validator *, expr_ty, expr_context_ty); -static int validate_pattern(struct validator *, pattern_ty, int); - -static int -validate_name(PyObject *name) -{ - assert(PyUnicode_Check(name)); - static const char * const forbidden[] = { - "None", - "True", - "False", - NULL - }; - for (int i = 0; forbidden[i] != NULL; i++) { - if (_PyUnicode_EqualToASCIIString(name, forbidden[i])) { - PyErr_Format(PyExc_ValueError, "identifier field can't represent '%s' constant", forbidden[i]); - return 0; - } - } - return 1; -} - -static int -validate_comprehension(struct validator *state, asdl_comprehension_seq *gens) -{ - Py_ssize_t i; - if (!asdl_seq_LEN(gens)) { - PyErr_SetString(PyExc_ValueError, "comprehension with no generators"); - return 0; - } - for (i = 0; i < asdl_seq_LEN(gens); i++) { - comprehension_ty comp = asdl_seq_GET(gens, i); - if (!validate_expr(state, comp->target, Store) || - !validate_expr(state, comp->iter, Load) || - !validate_exprs(state, comp->ifs, Load, 0)) - return 0; - } - return 1; -} - -static int -validate_keywords(struct validator *state, asdl_keyword_seq *keywords) -{ - Py_ssize_t i; - for (i = 0; i < asdl_seq_LEN(keywords); i++) - if (!validate_expr(state, (asdl_seq_GET(keywords, i))->value, Load)) - return 0; - return 1; -} - -static int -validate_args(struct validator *state, asdl_arg_seq *args) -{ - Py_ssize_t i; - for (i = 0; i < asdl_seq_LEN(args); i++) { - arg_ty arg = asdl_seq_GET(args, i); - if (arg->annotation && !validate_expr(state, arg->annotation, Load)) - return 0; - } - return 1; -} - -static const char * -expr_context_name(expr_context_ty ctx) -{ - switch (ctx) { - case Load: - return "Load"; - case Store: - return "Store"; - case Del: - return "Del"; - // No default case so compiler emits warning for unhandled cases - } - Py_UNREACHABLE(); -} - -static int -validate_arguments(struct validator *state, arguments_ty args) -{ - if (!validate_args(state, args->posonlyargs) || !validate_args(state, args->args)) { - return 0; - } - if (args->vararg && args->vararg->annotation - && !validate_expr(state, args->vararg->annotation, Load)) { - return 0; - } - if (!validate_args(state, args->kwonlyargs)) - return 0; - if (args->kwarg && args->kwarg->annotation - && !validate_expr(state, args->kwarg->annotation, Load)) { - return 0; - } - if (asdl_seq_LEN(args->defaults) > asdl_seq_LEN(args->posonlyargs) + asdl_seq_LEN(args->args)) { - PyErr_SetString(PyExc_ValueError, "more positional defaults than args on arguments"); - return 0; - } - if (asdl_seq_LEN(args->kw_defaults) != asdl_seq_LEN(args->kwonlyargs)) { - PyErr_SetString(PyExc_ValueError, "length of kwonlyargs is not the same as " - "kw_defaults on arguments"); - return 0; - } - return validate_exprs(state, args->defaults, Load, 0) && validate_exprs(state, args->kw_defaults, Load, 1); -} - -static int -validate_constant(struct validator *state, PyObject *value) -{ - if (value == Py_None || value == Py_Ellipsis) - return 1; - - if (PyLong_CheckExact(value) - || PyFloat_CheckExact(value) - || PyComplex_CheckExact(value) - || PyBool_Check(value) - || PyUnicode_CheckExact(value) - || PyBytes_CheckExact(value)) - return 1; - - if (PyTuple_CheckExact(value) || PyFrozenSet_CheckExact(value)) { - if (++state->recursion_depth > state->recursion_limit) { - PyErr_SetString(PyExc_RecursionError, - "maximum recursion depth exceeded during compilation"); - return 0; - } - - PyObject *it = PyObject_GetIter(value); - if (it == NULL) - return 0; - - while (1) { - PyObject *item = PyIter_Next(it); - if (item == NULL) { - if (PyErr_Occurred()) { - Py_DECREF(it); - return 0; - } - break; - } - - if (!validate_constant(state, item)) { - Py_DECREF(it); - Py_DECREF(item); - return 0; - } - Py_DECREF(item); - } - - Py_DECREF(it); - --state->recursion_depth; - return 1; - } - - if (!PyErr_Occurred()) { - PyErr_Format(PyExc_TypeError, - "got an invalid type in Constant: %s", - _PyType_Name(Py_TYPE(value))); - } - return 0; -} - -static int -validate_expr(struct validator *state, expr_ty exp, expr_context_ty ctx) -{ - int ret = -1; - if (++state->recursion_depth > state->recursion_limit) { - PyErr_SetString(PyExc_RecursionError, - "maximum recursion depth exceeded during compilation"); - return 0; - } - int check_ctx = 1; - expr_context_ty actual_ctx; - - /* First check expression context. */ - switch (exp->kind) { - case Attribute_kind: - actual_ctx = exp->v.Attribute.ctx; - break; - case Subscript_kind: - actual_ctx = exp->v.Subscript.ctx; - break; - case Starred_kind: - actual_ctx = exp->v.Starred.ctx; - break; - case Name_kind: - if (!validate_name(exp->v.Name.id)) { - return 0; - } - actual_ctx = exp->v.Name.ctx; - break; - case List_kind: - actual_ctx = exp->v.List.ctx; - break; - case Tuple_kind: - actual_ctx = exp->v.Tuple.ctx; - break; - default: - if (ctx != Load) { - PyErr_Format(PyExc_ValueError, "expression which can't be " - "assigned to in %s context", expr_context_name(ctx)); - return 0; - } - check_ctx = 0; - /* set actual_ctx to prevent gcc warning */ - actual_ctx = 0; - } - if (check_ctx && actual_ctx != ctx) { - PyErr_Format(PyExc_ValueError, "expression must have %s context but has %s instead", - expr_context_name(ctx), expr_context_name(actual_ctx)); - return 0; - } - - /* Now validate expression. */ - switch (exp->kind) { - case BoolOp_kind: - if (asdl_seq_LEN(exp->v.BoolOp.values) < 2) { - PyErr_SetString(PyExc_ValueError, "BoolOp with less than 2 values"); - return 0; - } - ret = validate_exprs(state, exp->v.BoolOp.values, Load, 0); - break; - case BinOp_kind: - ret = validate_expr(state, exp->v.BinOp.left, Load) && - validate_expr(state, exp->v.BinOp.right, Load); - break; - case UnaryOp_kind: - ret = validate_expr(state, exp->v.UnaryOp.operand, Load); - break; - case Lambda_kind: - ret = validate_arguments(state, exp->v.Lambda.args) && - validate_expr(state, exp->v.Lambda.body, Load); - break; - case IfExp_kind: - ret = validate_expr(state, exp->v.IfExp.test, Load) && - validate_expr(state, exp->v.IfExp.body, Load) && - validate_expr(state, exp->v.IfExp.orelse, Load); - break; - case Dict_kind: - if (asdl_seq_LEN(exp->v.Dict.keys) != asdl_seq_LEN(exp->v.Dict.values)) { - PyErr_SetString(PyExc_ValueError, - "Dict doesn't have the same number of keys as values"); - return 0; - } - /* null_ok=1 for keys expressions to allow dict unpacking to work in - dict literals, i.e. ``{**{a:b}}`` */ - ret = validate_exprs(state, exp->v.Dict.keys, Load, /*null_ok=*/ 1) && - validate_exprs(state, exp->v.Dict.values, Load, /*null_ok=*/ 0); - break; - case Set_kind: - ret = validate_exprs(state, exp->v.Set.elts, Load, 0); - break; -#define COMP(NAME) \ - case NAME ## _kind: \ - ret = validate_comprehension(state, exp->v.NAME.generators) && \ - validate_expr(state, exp->v.NAME.elt, Load); \ - break; - COMP(ListComp) - COMP(SetComp) - COMP(GeneratorExp) -#undef COMP - case DictComp_kind: - ret = validate_comprehension(state, exp->v.DictComp.generators) && - validate_expr(state, exp->v.DictComp.key, Load) && - validate_expr(state, exp->v.DictComp.value, Load); - break; - case Yield_kind: - ret = !exp->v.Yield.value || validate_expr(state, exp->v.Yield.value, Load); - break; - case YieldFrom_kind: - ret = validate_expr(state, exp->v.YieldFrom.value, Load); - break; - case Await_kind: - ret = validate_expr(state, exp->v.Await.value, Load); - break; - case Compare_kind: - if (!asdl_seq_LEN(exp->v.Compare.comparators)) { - PyErr_SetString(PyExc_ValueError, "Compare with no comparators"); - return 0; - } - if (asdl_seq_LEN(exp->v.Compare.comparators) != - asdl_seq_LEN(exp->v.Compare.ops)) { - PyErr_SetString(PyExc_ValueError, "Compare has a different number " - "of comparators and operands"); - return 0; - } - ret = validate_exprs(state, exp->v.Compare.comparators, Load, 0) && - validate_expr(state, exp->v.Compare.left, Load); - break; - case Call_kind: - ret = validate_expr(state, exp->v.Call.func, Load) && - validate_exprs(state, exp->v.Call.args, Load, 0) && - validate_keywords(state, exp->v.Call.keywords); - break; - case Constant_kind: - if (!validate_constant(state, exp->v.Constant.value)) { - return 0; - } - ret = 1; - break; - case JoinedStr_kind: - ret = validate_exprs(state, exp->v.JoinedStr.values, Load, 0); - break; - case FormattedValue_kind: - if (validate_expr(state, exp->v.FormattedValue.value, Load) == 0) - return 0; - if (exp->v.FormattedValue.format_spec) { - ret = validate_expr(state, exp->v.FormattedValue.format_spec, Load); - break; - } - ret = 1; - break; - case Attribute_kind: - ret = validate_expr(state, exp->v.Attribute.value, Load); - break; - case Subscript_kind: - ret = validate_expr(state, exp->v.Subscript.slice, Load) && - validate_expr(state, exp->v.Subscript.value, Load); - break; - case Starred_kind: - ret = validate_expr(state, exp->v.Starred.value, ctx); - break; - case Slice_kind: - ret = (!exp->v.Slice.lower || validate_expr(state, exp->v.Slice.lower, Load)) && - (!exp->v.Slice.upper || validate_expr(state, exp->v.Slice.upper, Load)) && - (!exp->v.Slice.step || validate_expr(state, exp->v.Slice.step, Load)); - break; - case List_kind: - ret = validate_exprs(state, exp->v.List.elts, ctx, 0); - break; - case Tuple_kind: - ret = validate_exprs(state, exp->v.Tuple.elts, ctx, 0); - break; - case NamedExpr_kind: - ret = validate_expr(state, exp->v.NamedExpr.value, Load); - break; - /* This last case doesn't have any checking. */ - case Name_kind: - ret = 1; - break; - // No default case so compiler emits warning for unhandled cases - } - if (ret < 0) { - PyErr_SetString(PyExc_SystemError, "unexpected expression"); - ret = 0; - } - state->recursion_depth--; - return ret; -} - - -// Note: the ensure_literal_* functions are only used to validate a restricted -// set of non-recursive literals that have already been checked with -// validate_expr, so they don't accept the validator state -static int -ensure_literal_number(expr_ty exp, bool allow_real, bool allow_imaginary) -{ - assert(exp->kind == Constant_kind); - PyObject *value = exp->v.Constant.value; - return (allow_real && PyFloat_CheckExact(value)) || - (allow_real && PyLong_CheckExact(value)) || - (allow_imaginary && PyComplex_CheckExact(value)); -} - -static int -ensure_literal_negative(expr_ty exp, bool allow_real, bool allow_imaginary) -{ - assert(exp->kind == UnaryOp_kind); - // Must be negation ... - if (exp->v.UnaryOp.op != USub) { - return 0; - } - // ... of a constant ... - expr_ty operand = exp->v.UnaryOp.operand; - if (operand->kind != Constant_kind) { - return 0; - } - // ... number - return ensure_literal_number(operand, allow_real, allow_imaginary); -} - -static int -ensure_literal_complex(expr_ty exp) -{ - assert(exp->kind == BinOp_kind); - expr_ty left = exp->v.BinOp.left; - expr_ty right = exp->v.BinOp.right; - // Ensure op is addition or subtraction - if (exp->v.BinOp.op != Add && exp->v.BinOp.op != Sub) { - return 0; - } - // Check LHS is a real number (potentially signed) - switch (left->kind) - { - case Constant_kind: - if (!ensure_literal_number(left, /*real=*/true, /*imaginary=*/false)) { - return 0; - } - break; - case UnaryOp_kind: - if (!ensure_literal_negative(left, /*real=*/true, /*imaginary=*/false)) { - return 0; - } - break; - default: - return 0; - } - // Check RHS is an imaginary number (no separate sign allowed) - switch (right->kind) - { - case Constant_kind: - if (!ensure_literal_number(right, /*real=*/false, /*imaginary=*/true)) { - return 0; - } - break; - default: - return 0; - } - return 1; -} - -static int -validate_pattern_match_value(struct validator *state, expr_ty exp) -{ - if (!validate_expr(state, exp, Load)) { - return 0; - } - - switch (exp->kind) - { - case Constant_kind: - /* Ellipsis and immutable sequences are not allowed. - For True, False and None, MatchSingleton() should - be used */ - if (!validate_expr(state, exp, Load)) { - return 0; - } - PyObject *literal = exp->v.Constant.value; - if (PyLong_CheckExact(literal) || PyFloat_CheckExact(literal) || - PyBytes_CheckExact(literal) || PyComplex_CheckExact(literal) || - PyUnicode_CheckExact(literal)) { - return 1; - } - PyErr_SetString(PyExc_ValueError, - "unexpected constant inside of a literal pattern"); - return 0; - case Attribute_kind: - // Constants and attribute lookups are always permitted - return 1; - case UnaryOp_kind: - // Negated numbers are permitted (whether real or imaginary) - // Compiler will complain if AST folding doesn't create a constant - if (ensure_literal_negative(exp, /*real=*/true, /*imaginary=*/true)) { - return 1; - } - break; - case BinOp_kind: - // Complex literals are permitted - // Compiler will complain if AST folding doesn't create a constant - if (ensure_literal_complex(exp)) { - return 1; - } - break; - case JoinedStr_kind: - // Handled in the later stages - return 1; - default: - break; - } - PyErr_SetString(PyExc_ValueError, - "patterns may only match literals and attribute lookups"); - return 0; -} - -static int -validate_capture(PyObject *name) -{ - if (_PyUnicode_EqualToASCIIString(name, "_")) { - PyErr_Format(PyExc_ValueError, "can't capture name '_' in patterns"); - return 0; - } - return validate_name(name); -} - -static int -validate_pattern(struct validator *state, pattern_ty p, int star_ok) -{ - int ret = -1; - if (++state->recursion_depth > state->recursion_limit) { - PyErr_SetString(PyExc_RecursionError, - "maximum recursion depth exceeded during compilation"); - return 0; - } - switch (p->kind) { - case MatchValue_kind: - ret = validate_pattern_match_value(state, p->v.MatchValue.value); - break; - case MatchSingleton_kind: - ret = p->v.MatchSingleton.value == Py_None || PyBool_Check(p->v.MatchSingleton.value); - if (!ret) { - PyErr_SetString(PyExc_ValueError, - "MatchSingleton can only contain True, False and None"); - } - break; - case MatchSequence_kind: - ret = validate_patterns(state, p->v.MatchSequence.patterns, /*star_ok=*/1); - break; - case MatchMapping_kind: - if (asdl_seq_LEN(p->v.MatchMapping.keys) != asdl_seq_LEN(p->v.MatchMapping.patterns)) { - PyErr_SetString(PyExc_ValueError, - "MatchMapping doesn't have the same number of keys as patterns"); - ret = 0; - break; - } - - if (p->v.MatchMapping.rest && !validate_capture(p->v.MatchMapping.rest)) { - ret = 0; - break; - } - - asdl_expr_seq *keys = p->v.MatchMapping.keys; - for (Py_ssize_t i = 0; i < asdl_seq_LEN(keys); i++) { - expr_ty key = asdl_seq_GET(keys, i); - if (key->kind == Constant_kind) { - PyObject *literal = key->v.Constant.value; - if (literal == Py_None || PyBool_Check(literal)) { - /* validate_pattern_match_value will ensure the key - doesn't contain True, False and None but it is - syntactically valid, so we will pass those on in - a special case. */ - continue; - } - } - if (!validate_pattern_match_value(state, key)) { - ret = 0; - break; - } - } - - ret = validate_patterns(state, p->v.MatchMapping.patterns, /*star_ok=*/0); - break; - case MatchClass_kind: - if (asdl_seq_LEN(p->v.MatchClass.kwd_attrs) != asdl_seq_LEN(p->v.MatchClass.kwd_patterns)) { - PyErr_SetString(PyExc_ValueError, - "MatchClass doesn't have the same number of keyword attributes as patterns"); - ret = 0; - break; - } - if (!validate_expr(state, p->v.MatchClass.cls, Load)) { - ret = 0; - break; - } - - expr_ty cls = p->v.MatchClass.cls; - while (1) { - if (cls->kind == Name_kind) { - break; - } - else if (cls->kind == Attribute_kind) { - cls = cls->v.Attribute.value; - continue; - } - else { - PyErr_SetString(PyExc_ValueError, - "MatchClass cls field can only contain Name or Attribute nodes."); - ret = 0; - break; - } - } - - for (Py_ssize_t i = 0; i < asdl_seq_LEN(p->v.MatchClass.kwd_attrs); i++) { - PyObject *identifier = asdl_seq_GET(p->v.MatchClass.kwd_attrs, i); - if (!validate_name(identifier)) { - ret = 0; - break; - } - } - - if (!validate_patterns(state, p->v.MatchClass.patterns, /*star_ok=*/0)) { - ret = 0; - break; - } - - ret = validate_patterns(state, p->v.MatchClass.kwd_patterns, /*star_ok=*/0); - break; - case MatchStar_kind: - if (!star_ok) { - PyErr_SetString(PyExc_ValueError, "can't use MatchStar here"); - ret = 0; - break; - } - ret = p->v.MatchStar.name == NULL || validate_capture(p->v.MatchStar.name); - break; - case MatchAs_kind: - if (p->v.MatchAs.name && !validate_capture(p->v.MatchAs.name)) { - ret = 0; - break; - } - if (p->v.MatchAs.pattern == NULL) { - ret = 1; - } - else if (p->v.MatchAs.name == NULL) { - PyErr_SetString(PyExc_ValueError, - "MatchAs must specify a target name if a pattern is given"); - ret = 0; - } - else { - ret = validate_pattern(state, p->v.MatchAs.pattern, /*star_ok=*/0); - } - break; - case MatchOr_kind: - if (asdl_seq_LEN(p->v.MatchOr.patterns) < 2) { - PyErr_SetString(PyExc_ValueError, - "MatchOr requires at least 2 patterns"); - ret = 0; - break; - } - ret = validate_patterns(state, p->v.MatchOr.patterns, /*star_ok=*/0); - break; - // No default case, so the compiler will emit a warning if new pattern - // kinds are added without being handled here - } - if (ret < 0) { - PyErr_SetString(PyExc_SystemError, "unexpected pattern"); - ret = 0; - } - state->recursion_depth--; - return ret; -} - -static int -_validate_nonempty_seq(asdl_seq *seq, const char *what, const char *owner) -{ - if (asdl_seq_LEN(seq)) - return 1; - PyErr_Format(PyExc_ValueError, "empty %s on %s", what, owner); - return 0; -} -#define validate_nonempty_seq(seq, what, owner) _validate_nonempty_seq((asdl_seq*)seq, what, owner) - -static int -validate_assignlist(struct validator *state, asdl_expr_seq *targets, expr_context_ty ctx) -{ - return validate_nonempty_seq(targets, "targets", ctx == Del ? "Delete" : "Assign") && - validate_exprs(state, targets, ctx, 0); -} - -static int -validate_body(struct validator *state, asdl_stmt_seq *body, const char *owner) -{ - return validate_nonempty_seq(body, "body", owner) && validate_stmts(state, body); -} - -static int -validate_stmt(struct validator *state, stmt_ty stmt) -{ - int ret = -1; - Py_ssize_t i; - if (++state->recursion_depth > state->recursion_limit) { - PyErr_SetString(PyExc_RecursionError, - "maximum recursion depth exceeded during compilation"); - return 0; - } - switch (stmt->kind) { - case FunctionDef_kind: - ret = validate_body(state, stmt->v.FunctionDef.body, "FunctionDef") && - validate_arguments(state, stmt->v.FunctionDef.args) && - validate_exprs(state, stmt->v.FunctionDef.decorator_list, Load, 0) && - (!stmt->v.FunctionDef.returns || - validate_expr(state, stmt->v.FunctionDef.returns, Load)); - break; - case ClassDef_kind: - ret = validate_body(state, stmt->v.ClassDef.body, "ClassDef") && - validate_exprs(state, stmt->v.ClassDef.bases, Load, 0) && - validate_keywords(state, stmt->v.ClassDef.keywords) && - validate_exprs(state, stmt->v.ClassDef.decorator_list, Load, 0); - break; - case Return_kind: - ret = !stmt->v.Return.value || validate_expr(state, stmt->v.Return.value, Load); - break; - case Delete_kind: - ret = validate_assignlist(state, stmt->v.Delete.targets, Del); - break; - case Assign_kind: - ret = validate_assignlist(state, stmt->v.Assign.targets, Store) && - validate_expr(state, stmt->v.Assign.value, Load); - break; - case AugAssign_kind: - ret = validate_expr(state, stmt->v.AugAssign.target, Store) && - validate_expr(state, stmt->v.AugAssign.value, Load); - break; - case AnnAssign_kind: - if (stmt->v.AnnAssign.target->kind != Name_kind && - stmt->v.AnnAssign.simple) { - PyErr_SetString(PyExc_TypeError, - "AnnAssign with simple non-Name target"); - return 0; - } - ret = validate_expr(state, stmt->v.AnnAssign.target, Store) && - (!stmt->v.AnnAssign.value || - validate_expr(state, stmt->v.AnnAssign.value, Load)) && - validate_expr(state, stmt->v.AnnAssign.annotation, Load); - break; - case For_kind: - ret = validate_expr(state, stmt->v.For.target, Store) && - validate_expr(state, stmt->v.For.iter, Load) && - validate_body(state, stmt->v.For.body, "For") && - validate_stmts(state, stmt->v.For.orelse); - break; - case AsyncFor_kind: - ret = validate_expr(state, stmt->v.AsyncFor.target, Store) && - validate_expr(state, stmt->v.AsyncFor.iter, Load) && - validate_body(state, stmt->v.AsyncFor.body, "AsyncFor") && - validate_stmts(state, stmt->v.AsyncFor.orelse); - break; - case While_kind: - ret = validate_expr(state, stmt->v.While.test, Load) && - validate_body(state, stmt->v.While.body, "While") && - validate_stmts(state, stmt->v.While.orelse); - break; - case If_kind: - ret = validate_expr(state, stmt->v.If.test, Load) && - validate_body(state, stmt->v.If.body, "If") && - validate_stmts(state, stmt->v.If.orelse); - break; - case With_kind: - if (!validate_nonempty_seq(stmt->v.With.items, "items", "With")) - return 0; - for (i = 0; i < asdl_seq_LEN(stmt->v.With.items); i++) { - withitem_ty item = asdl_seq_GET(stmt->v.With.items, i); - if (!validate_expr(state, item->context_expr, Load) || - (item->optional_vars && !validate_expr(state, item->optional_vars, Store))) - return 0; - } - ret = validate_body(state, stmt->v.With.body, "With"); - break; - case AsyncWith_kind: - if (!validate_nonempty_seq(stmt->v.AsyncWith.items, "items", "AsyncWith")) - return 0; - for (i = 0; i < asdl_seq_LEN(stmt->v.AsyncWith.items); i++) { - withitem_ty item = asdl_seq_GET(stmt->v.AsyncWith.items, i); - if (!validate_expr(state, item->context_expr, Load) || - (item->optional_vars && !validate_expr(state, item->optional_vars, Store))) - return 0; - } - ret = validate_body(state, stmt->v.AsyncWith.body, "AsyncWith"); - break; - case Match_kind: - if (!validate_expr(state, stmt->v.Match.subject, Load) - || !validate_nonempty_seq(stmt->v.Match.cases, "cases", "Match")) { - return 0; - } - for (i = 0; i < asdl_seq_LEN(stmt->v.Match.cases); i++) { - match_case_ty m = asdl_seq_GET(stmt->v.Match.cases, i); - if (!validate_pattern(state, m->pattern, /*star_ok=*/0) - || (m->guard && !validate_expr(state, m->guard, Load)) - || !validate_body(state, m->body, "match_case")) { - return 0; - } - } - ret = 1; - break; - case Raise_kind: - if (stmt->v.Raise.exc) { - ret = validate_expr(state, stmt->v.Raise.exc, Load) && - (!stmt->v.Raise.cause || validate_expr(state, stmt->v.Raise.cause, Load)); - break; - } - if (stmt->v.Raise.cause) { - PyErr_SetString(PyExc_ValueError, "Raise with cause but no exception"); - return 0; - } - ret = 1; - break; - case Try_kind: - if (!validate_body(state, stmt->v.Try.body, "Try")) - return 0; - if (!asdl_seq_LEN(stmt->v.Try.handlers) && - !asdl_seq_LEN(stmt->v.Try.finalbody)) { - PyErr_SetString(PyExc_ValueError, "Try has neither except handlers nor finalbody"); - return 0; - } - if (!asdl_seq_LEN(stmt->v.Try.handlers) && - asdl_seq_LEN(stmt->v.Try.orelse)) { - PyErr_SetString(PyExc_ValueError, "Try has orelse but no except handlers"); - return 0; - } - for (i = 0; i < asdl_seq_LEN(stmt->v.Try.handlers); i++) { - excepthandler_ty handler = asdl_seq_GET(stmt->v.Try.handlers, i); - if ((handler->v.ExceptHandler.type && - !validate_expr(state, handler->v.ExceptHandler.type, Load)) || - !validate_body(state, handler->v.ExceptHandler.body, "ExceptHandler")) - return 0; - } - ret = (!asdl_seq_LEN(stmt->v.Try.finalbody) || - validate_stmts(state, stmt->v.Try.finalbody)) && - (!asdl_seq_LEN(stmt->v.Try.orelse) || - validate_stmts(state, stmt->v.Try.orelse)); - break; - case Assert_kind: - ret = validate_expr(state, stmt->v.Assert.test, Load) && - (!stmt->v.Assert.msg || validate_expr(state, stmt->v.Assert.msg, Load)); - break; - case Import_kind: - ret = validate_nonempty_seq(stmt->v.Import.names, "names", "Import"); - break; - case ImportFrom_kind: - if (stmt->v.ImportFrom.level < 0) { - PyErr_SetString(PyExc_ValueError, "Negative ImportFrom level"); - return 0; - } - ret = validate_nonempty_seq(stmt->v.ImportFrom.names, "names", "ImportFrom"); - break; - case Global_kind: - ret = validate_nonempty_seq(stmt->v.Global.names, "names", "Global"); - break; - case Nonlocal_kind: - ret = validate_nonempty_seq(stmt->v.Nonlocal.names, "names", "Nonlocal"); - break; - case Expr_kind: - ret = validate_expr(state, stmt->v.Expr.value, Load); - break; - case AsyncFunctionDef_kind: - ret = validate_body(state, stmt->v.AsyncFunctionDef.body, "AsyncFunctionDef") && - validate_arguments(state, stmt->v.AsyncFunctionDef.args) && - validate_exprs(state, stmt->v.AsyncFunctionDef.decorator_list, Load, 0) && - (!stmt->v.AsyncFunctionDef.returns || - validate_expr(state, stmt->v.AsyncFunctionDef.returns, Load)); - break; - case Pass_kind: - case Break_kind: - case Continue_kind: - ret = 1; - break; - // No default case so compiler emits warning for unhandled cases - } - if (ret < 0) { - PyErr_SetString(PyExc_SystemError, "unexpected statement"); - ret = 0; - } - state->recursion_depth--; - return ret; -} - -static int -validate_stmts(struct validator *state, asdl_stmt_seq *seq) -{ - Py_ssize_t i; - for (i = 0; i < asdl_seq_LEN(seq); i++) { - stmt_ty stmt = asdl_seq_GET(seq, i); - if (stmt) { - if (!validate_stmt(state, stmt)) - return 0; - } - else { - PyErr_SetString(PyExc_ValueError, - "None disallowed in statement list"); - return 0; - } - } - return 1; -} - -static int -validate_exprs(struct validator *state, asdl_expr_seq *exprs, expr_context_ty ctx, int null_ok) -{ - Py_ssize_t i; - for (i = 0; i < asdl_seq_LEN(exprs); i++) { - expr_ty expr = asdl_seq_GET(exprs, i); - if (expr) { - if (!validate_expr(state, expr, ctx)) - return 0; - } - else if (!null_ok) { - PyErr_SetString(PyExc_ValueError, - "None disallowed in expression list"); - return 0; - } - - } - return 1; -} - -static int -validate_patterns(struct validator *state, asdl_pattern_seq *patterns, int star_ok) -{ - Py_ssize_t i; - for (i = 0; i < asdl_seq_LEN(patterns); i++) { - pattern_ty pattern = asdl_seq_GET(patterns, i); - if (!validate_pattern(state, pattern, star_ok)) { - return 0; - } - } - return 1; -} - - -/* See comments in symtable.c. */ -#define COMPILER_STACK_FRAME_SCALE 3 - -int -_PyAST_Validate(mod_ty mod) -{ - int res = -1; - struct validator state; - PyThreadState *tstate; - int recursion_limit = Py_GetRecursionLimit(); - int starting_recursion_depth; - - /* Setup recursion depth check counters */ - tstate = _PyThreadState_GET(); - if (!tstate) { - return 0; - } - /* Be careful here to prevent overflow. */ - starting_recursion_depth = (tstate->recursion_depth < INT_MAX / COMPILER_STACK_FRAME_SCALE) ? - tstate->recursion_depth * COMPILER_STACK_FRAME_SCALE : tstate->recursion_depth; - state.recursion_depth = starting_recursion_depth; - state.recursion_limit = (recursion_limit < INT_MAX / COMPILER_STACK_FRAME_SCALE) ? - recursion_limit * COMPILER_STACK_FRAME_SCALE : recursion_limit; - - switch (mod->kind) { - case Module_kind: - res = validate_stmts(&state, mod->v.Module.body); - break; - case Interactive_kind: - res = validate_stmts(&state, mod->v.Interactive.body); - break; - case Expression_kind: - res = validate_expr(&state, mod->v.Expression.body, Load); - break; - case FunctionType_kind: - res = validate_exprs(&state, mod->v.FunctionType.argtypes, Load, /*null_ok=*/0) && - validate_expr(&state, mod->v.FunctionType.returns, Load); - break; - // No default case so compiler emits warning for unhandled cases - } - - if (res < 0) { - PyErr_SetString(PyExc_SystemError, "impossible module node"); - return 0; - } - - /* Check that the recursion depth counting balanced correctly */ - if (res && state.recursion_depth != starting_recursion_depth) { - PyErr_Format(PyExc_SystemError, - "AST validator recursion depth mismatch (before=%d, after=%d)", - starting_recursion_depth, state.recursion_depth); - return 0; - } - return res; -} - -PyObject * -_PyAST_GetDocString(asdl_stmt_seq *body) -{ - if (!asdl_seq_LEN(body)) { - return NULL; - } - stmt_ty st = asdl_seq_GET(body, 0); - if (st->kind != Expr_kind) { - return NULL; - } - expr_ty e = st->v.Expr.value; - if (e->kind == Constant_kind && PyUnicode_CheckExact(e->v.Constant.value)) { - return e->v.Constant.value; - } - return NULL; -} diff --git a/contrib/tools/python3/src/Python/ast_opt.c b/contrib/tools/python3/src/Python/ast_opt.c deleted file mode 100644 index c1fdea3a88c..00000000000 --- a/contrib/tools/python3/src/Python/ast_opt.c +++ /dev/null @@ -1,889 +0,0 @@ -/* AST Optimizer */ -#include "Python.h" -#include "pycore_ast.h" // _PyAST_GetDocString() -#include "pycore_compile.h" // _PyASTOptimizeState -#include "pycore_pystate.h" // _PyThreadState_GET() - - -static int -make_const(expr_ty node, PyObject *val, PyArena *arena) -{ - // Even if no new value was calculated, make_const may still - // need to clear an error (e.g. for division by zero) - if (val == NULL) { - if (PyErr_ExceptionMatches(PyExc_KeyboardInterrupt)) { - return 0; - } - PyErr_Clear(); - return 1; - } - if (_PyArena_AddPyObject(arena, val) < 0) { - Py_DECREF(val); - return 0; - } - node->kind = Constant_kind; - node->v.Constant.kind = NULL; - node->v.Constant.value = val; - return 1; -} - -#define COPY_NODE(TO, FROM) (memcpy((TO), (FROM), sizeof(struct _expr))) - -static PyObject* -unary_not(PyObject *v) -{ - int r = PyObject_IsTrue(v); - if (r < 0) - return NULL; - return PyBool_FromLong(!r); -} - -static int -fold_unaryop(expr_ty node, PyArena *arena, _PyASTOptimizeState *state) -{ - expr_ty arg = node->v.UnaryOp.operand; - - if (arg->kind != Constant_kind) { - /* Fold not into comparison */ - if (node->v.UnaryOp.op == Not && arg->kind == Compare_kind && - asdl_seq_LEN(arg->v.Compare.ops) == 1) { - /* Eq and NotEq are often implemented in terms of one another, so - folding not (self == other) into self != other breaks implementation - of !=. Detecting such cases doesn't seem worthwhile. - Python uses </> for 'is subset'/'is superset' operations on sets. - They don't satisfy not folding laws. */ - cmpop_ty op = asdl_seq_GET(arg->v.Compare.ops, 0); - switch (op) { - case Is: - op = IsNot; - break; - case IsNot: - op = Is; - break; - case In: - op = NotIn; - break; - case NotIn: - op = In; - break; - // The remaining comparison operators can't be safely inverted - case Eq: - case NotEq: - case Lt: - case LtE: - case Gt: - case GtE: - op = 0; // The AST enums leave "0" free as an "unused" marker - break; - // No default case, so the compiler will emit a warning if new - // comparison operators are added without being handled here - } - if (op) { - asdl_seq_SET(arg->v.Compare.ops, 0, op); - COPY_NODE(node, arg); - return 1; - } - } - return 1; - } - - typedef PyObject *(*unary_op)(PyObject*); - static const unary_op ops[] = { - [Invert] = PyNumber_Invert, - [Not] = unary_not, - [UAdd] = PyNumber_Positive, - [USub] = PyNumber_Negative, - }; - PyObject *newval = ops[node->v.UnaryOp.op](arg->v.Constant.value); - return make_const(node, newval, arena); -} - -/* Check whether a collection doesn't containing too much items (including - subcollections). This protects from creating a constant that needs - too much time for calculating a hash. - "limit" is the maximal number of items. - Returns the negative number if the total number of items exceeds the - limit. Otherwise returns the limit minus the total number of items. -*/ - -static Py_ssize_t -check_complexity(PyObject *obj, Py_ssize_t limit) -{ - if (PyTuple_Check(obj)) { - Py_ssize_t i; - limit -= PyTuple_GET_SIZE(obj); - for (i = 0; limit >= 0 && i < PyTuple_GET_SIZE(obj); i++) { - limit = check_complexity(PyTuple_GET_ITEM(obj, i), limit); - } - return limit; - } - else if (PyFrozenSet_Check(obj)) { - Py_ssize_t i = 0; - PyObject *item; - Py_hash_t hash; - limit -= PySet_GET_SIZE(obj); - while (limit >= 0 && _PySet_NextEntry(obj, &i, &item, &hash)) { - limit = check_complexity(item, limit); - } - } - return limit; -} - -#define MAX_INT_SIZE 128 /* bits */ -#define MAX_COLLECTION_SIZE 256 /* items */ -#define MAX_STR_SIZE 4096 /* characters */ -#define MAX_TOTAL_ITEMS 1024 /* including nested collections */ - -static PyObject * -safe_multiply(PyObject *v, PyObject *w) -{ - if (PyLong_Check(v) && PyLong_Check(w) && Py_SIZE(v) && Py_SIZE(w)) { - size_t vbits = _PyLong_NumBits(v); - size_t wbits = _PyLong_NumBits(w); - if (vbits == (size_t)-1 || wbits == (size_t)-1) { - return NULL; - } - if (vbits + wbits > MAX_INT_SIZE) { - return NULL; - } - } - else if (PyLong_Check(v) && (PyTuple_Check(w) || PyFrozenSet_Check(w))) { - Py_ssize_t size = PyTuple_Check(w) ? PyTuple_GET_SIZE(w) : - PySet_GET_SIZE(w); - if (size) { - long n = PyLong_AsLong(v); - if (n < 0 || n > MAX_COLLECTION_SIZE / size) { - return NULL; - } - if (n && check_complexity(w, MAX_TOTAL_ITEMS / n) < 0) { - return NULL; - } - } - } - else if (PyLong_Check(v) && (PyUnicode_Check(w) || PyBytes_Check(w))) { - Py_ssize_t size = PyUnicode_Check(w) ? PyUnicode_GET_LENGTH(w) : - PyBytes_GET_SIZE(w); - if (size) { - long n = PyLong_AsLong(v); - if (n < 0 || n > MAX_STR_SIZE / size) { - return NULL; - } - } - } - else if (PyLong_Check(w) && - (PyTuple_Check(v) || PyFrozenSet_Check(v) || - PyUnicode_Check(v) || PyBytes_Check(v))) - { - return safe_multiply(w, v); - } - - return PyNumber_Multiply(v, w); -} - -static PyObject * -safe_power(PyObject *v, PyObject *w) -{ - if (PyLong_Check(v) && PyLong_Check(w) && Py_SIZE(v) && Py_SIZE(w) > 0) { - size_t vbits = _PyLong_NumBits(v); - size_t wbits = PyLong_AsSize_t(w); - if (vbits == (size_t)-1 || wbits == (size_t)-1) { - return NULL; - } - if (vbits > MAX_INT_SIZE / wbits) { - return NULL; - } - } - - return PyNumber_Power(v, w, Py_None); -} - -static PyObject * -safe_lshift(PyObject *v, PyObject *w) -{ - if (PyLong_Check(v) && PyLong_Check(w) && Py_SIZE(v) && Py_SIZE(w)) { - size_t vbits = _PyLong_NumBits(v); - size_t wbits = PyLong_AsSize_t(w); - if (vbits == (size_t)-1 || wbits == (size_t)-1) { - return NULL; - } - if (wbits > MAX_INT_SIZE || vbits > MAX_INT_SIZE - wbits) { - return NULL; - } - } - - return PyNumber_Lshift(v, w); -} - -static PyObject * -safe_mod(PyObject *v, PyObject *w) -{ - if (PyUnicode_Check(v) || PyBytes_Check(v)) { - return NULL; - } - - return PyNumber_Remainder(v, w); -} - -static int -fold_binop(expr_ty node, PyArena *arena, _PyASTOptimizeState *state) -{ - expr_ty lhs, rhs; - lhs = node->v.BinOp.left; - rhs = node->v.BinOp.right; - if (lhs->kind != Constant_kind || rhs->kind != Constant_kind) { - return 1; - } - - PyObject *lv = lhs->v.Constant.value; - PyObject *rv = rhs->v.Constant.value; - PyObject *newval = NULL; - - switch (node->v.BinOp.op) { - case Add: - newval = PyNumber_Add(lv, rv); - break; - case Sub: - newval = PyNumber_Subtract(lv, rv); - break; - case Mult: - newval = safe_multiply(lv, rv); - break; - case Div: - newval = PyNumber_TrueDivide(lv, rv); - break; - case FloorDiv: - newval = PyNumber_FloorDivide(lv, rv); - break; - case Mod: - newval = safe_mod(lv, rv); - break; - case Pow: - newval = safe_power(lv, rv); - break; - case LShift: - newval = safe_lshift(lv, rv); - break; - case RShift: - newval = PyNumber_Rshift(lv, rv); - break; - case BitOr: - newval = PyNumber_Or(lv, rv); - break; - case BitXor: - newval = PyNumber_Xor(lv, rv); - break; - case BitAnd: - newval = PyNumber_And(lv, rv); - break; - // No builtin constants implement the following operators - case MatMult: - return 1; - // No default case, so the compiler will emit a warning if new binary - // operators are added without being handled here - } - - return make_const(node, newval, arena); -} - -static PyObject* -make_const_tuple(asdl_expr_seq *elts) -{ - for (int i = 0; i < asdl_seq_LEN(elts); i++) { - expr_ty e = (expr_ty)asdl_seq_GET(elts, i); - if (e->kind != Constant_kind) { - return NULL; - } - } - - PyObject *newval = PyTuple_New(asdl_seq_LEN(elts)); - if (newval == NULL) { - return NULL; - } - - for (int i = 0; i < asdl_seq_LEN(elts); i++) { - expr_ty e = (expr_ty)asdl_seq_GET(elts, i); - PyObject *v = e->v.Constant.value; - Py_INCREF(v); - PyTuple_SET_ITEM(newval, i, v); - } - return newval; -} - -static int -fold_tuple(expr_ty node, PyArena *arena, _PyASTOptimizeState *state) -{ - PyObject *newval; - - if (node->v.Tuple.ctx != Load) - return 1; - - newval = make_const_tuple(node->v.Tuple.elts); - return make_const(node, newval, arena); -} - -static int -fold_subscr(expr_ty node, PyArena *arena, _PyASTOptimizeState *state) -{ - PyObject *newval; - expr_ty arg, idx; - - arg = node->v.Subscript.value; - idx = node->v.Subscript.slice; - if (node->v.Subscript.ctx != Load || - arg->kind != Constant_kind || - idx->kind != Constant_kind) - { - return 1; - } - - newval = PyObject_GetItem(arg->v.Constant.value, idx->v.Constant.value); - return make_const(node, newval, arena); -} - -/* Change literal list or set of constants into constant - tuple or frozenset respectively. Change literal list of - non-constants into tuple. - Used for right operand of "in" and "not in" tests and for iterable - in "for" loop and comprehensions. -*/ -static int -fold_iter(expr_ty arg, PyArena *arena, _PyASTOptimizeState *state) -{ - PyObject *newval; - if (arg->kind == List_kind) { - /* First change a list into tuple. */ - asdl_expr_seq *elts = arg->v.List.elts; - Py_ssize_t n = asdl_seq_LEN(elts); - for (Py_ssize_t i = 0; i < n; i++) { - expr_ty e = (expr_ty)asdl_seq_GET(elts, i); - if (e->kind == Starred_kind) { - return 1; - } - } - expr_context_ty ctx = arg->v.List.ctx; - arg->kind = Tuple_kind; - arg->v.Tuple.elts = elts; - arg->v.Tuple.ctx = ctx; - /* Try to create a constant tuple. */ - newval = make_const_tuple(elts); - } - else if (arg->kind == Set_kind) { - newval = make_const_tuple(arg->v.Set.elts); - if (newval) { - Py_SETREF(newval, PyFrozenSet_New(newval)); - } - } - else { - return 1; - } - return make_const(arg, newval, arena); -} - -static int -fold_compare(expr_ty node, PyArena *arena, _PyASTOptimizeState *state) -{ - asdl_int_seq *ops; - asdl_expr_seq *args; - Py_ssize_t i; - - ops = node->v.Compare.ops; - args = node->v.Compare.comparators; - /* TODO: optimize cases with literal arguments. */ - /* Change literal list or set in 'in' or 'not in' into - tuple or frozenset respectively. */ - i = asdl_seq_LEN(ops) - 1; - int op = asdl_seq_GET(ops, i); - if (op == In || op == NotIn) { - if (!fold_iter((expr_ty)asdl_seq_GET(args, i), arena, state)) { - return 0; - } - } - return 1; -} - -static int astfold_mod(mod_ty node_, PyArena *ctx_, _PyASTOptimizeState *state); -static int astfold_stmt(stmt_ty node_, PyArena *ctx_, _PyASTOptimizeState *state); -static int astfold_expr(expr_ty node_, PyArena *ctx_, _PyASTOptimizeState *state); -static int astfold_arguments(arguments_ty node_, PyArena *ctx_, _PyASTOptimizeState *state); -static int astfold_comprehension(comprehension_ty node_, PyArena *ctx_, _PyASTOptimizeState *state); -static int astfold_keyword(keyword_ty node_, PyArena *ctx_, _PyASTOptimizeState *state); -static int astfold_arg(arg_ty node_, PyArena *ctx_, _PyASTOptimizeState *state); -static int astfold_withitem(withitem_ty node_, PyArena *ctx_, _PyASTOptimizeState *state); -static int astfold_excepthandler(excepthandler_ty node_, PyArena *ctx_, _PyASTOptimizeState *state); -static int astfold_match_case(match_case_ty node_, PyArena *ctx_, _PyASTOptimizeState *state); -static int astfold_pattern(pattern_ty node_, PyArena *ctx_, _PyASTOptimizeState *state); - -#define CALL(FUNC, TYPE, ARG) \ - if (!FUNC((ARG), ctx_, state)) \ - return 0; - -#define CALL_OPT(FUNC, TYPE, ARG) \ - if ((ARG) != NULL && !FUNC((ARG), ctx_, state)) \ - return 0; - -#define CALL_SEQ(FUNC, TYPE, ARG) { \ - int i; \ - asdl_ ## TYPE ## _seq *seq = (ARG); /* avoid variable capture */ \ - for (i = 0; i < asdl_seq_LEN(seq); i++) { \ - TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, i); \ - if (elt != NULL && !FUNC(elt, ctx_, state)) \ - return 0; \ - } \ -} - -#define CALL_INT_SEQ(FUNC, TYPE, ARG) { \ - int i; \ - asdl_int_seq *seq = (ARG); /* avoid variable capture */ \ - for (i = 0; i < asdl_seq_LEN(seq); i++) { \ - TYPE elt = (TYPE)asdl_seq_GET(seq, i); \ - if (!FUNC(elt, ctx_, state)) \ - return 0; \ - } \ -} - -static int -astfold_body(asdl_stmt_seq *stmts, PyArena *ctx_, _PyASTOptimizeState *state) -{ - int docstring = _PyAST_GetDocString(stmts) != NULL; - CALL_SEQ(astfold_stmt, stmt, stmts); - if (!docstring && _PyAST_GetDocString(stmts) != NULL) { - stmt_ty st = (stmt_ty)asdl_seq_GET(stmts, 0); - asdl_expr_seq *values = _Py_asdl_expr_seq_new(1, ctx_); - if (!values) { - return 0; - } - asdl_seq_SET(values, 0, st->v.Expr.value); - expr_ty expr = _PyAST_JoinedStr(values, st->lineno, st->col_offset, - st->end_lineno, st->end_col_offset, - ctx_); - if (!expr) { - return 0; - } - st->v.Expr.value = expr; - } - return 1; -} - -static int -astfold_mod(mod_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) -{ - switch (node_->kind) { - case Module_kind: - CALL(astfold_body, asdl_seq, node_->v.Module.body); - break; - case Interactive_kind: - CALL_SEQ(astfold_stmt, stmt, node_->v.Interactive.body); - break; - case Expression_kind: - CALL(astfold_expr, expr_ty, node_->v.Expression.body); - break; - // The following top level nodes don't participate in constant folding - case FunctionType_kind: - break; - // No default case, so the compiler will emit a warning if new top level - // compilation nodes are added without being handled here - } - return 1; -} - -static int -astfold_expr(expr_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) -{ - if (++state->recursion_depth > state->recursion_limit) { - PyErr_SetString(PyExc_RecursionError, - "maximum recursion depth exceeded during compilation"); - return 0; - } - switch (node_->kind) { - case BoolOp_kind: - CALL_SEQ(astfold_expr, expr, node_->v.BoolOp.values); - break; - case BinOp_kind: - CALL(astfold_expr, expr_ty, node_->v.BinOp.left); - CALL(astfold_expr, expr_ty, node_->v.BinOp.right); - CALL(fold_binop, expr_ty, node_); - break; - case UnaryOp_kind: - CALL(astfold_expr, expr_ty, node_->v.UnaryOp.operand); - CALL(fold_unaryop, expr_ty, node_); - break; - case Lambda_kind: - CALL(astfold_arguments, arguments_ty, node_->v.Lambda.args); - CALL(astfold_expr, expr_ty, node_->v.Lambda.body); - break; - case IfExp_kind: - CALL(astfold_expr, expr_ty, node_->v.IfExp.test); - CALL(astfold_expr, expr_ty, node_->v.IfExp.body); - CALL(astfold_expr, expr_ty, node_->v.IfExp.orelse); - break; - case Dict_kind: - CALL_SEQ(astfold_expr, expr, node_->v.Dict.keys); - CALL_SEQ(astfold_expr, expr, node_->v.Dict.values); - break; - case Set_kind: - CALL_SEQ(astfold_expr, expr, node_->v.Set.elts); - break; - case ListComp_kind: - CALL(astfold_expr, expr_ty, node_->v.ListComp.elt); - CALL_SEQ(astfold_comprehension, comprehension, node_->v.ListComp.generators); - break; - case SetComp_kind: - CALL(astfold_expr, expr_ty, node_->v.SetComp.elt); - CALL_SEQ(astfold_comprehension, comprehension, node_->v.SetComp.generators); - break; - case DictComp_kind: - CALL(astfold_expr, expr_ty, node_->v.DictComp.key); - CALL(astfold_expr, expr_ty, node_->v.DictComp.value); - CALL_SEQ(astfold_comprehension, comprehension, node_->v.DictComp.generators); - break; - case GeneratorExp_kind: - CALL(astfold_expr, expr_ty, node_->v.GeneratorExp.elt); - CALL_SEQ(astfold_comprehension, comprehension, node_->v.GeneratorExp.generators); - break; - case Await_kind: - CALL(astfold_expr, expr_ty, node_->v.Await.value); - break; - case Yield_kind: - CALL_OPT(astfold_expr, expr_ty, node_->v.Yield.value); - break; - case YieldFrom_kind: - CALL(astfold_expr, expr_ty, node_->v.YieldFrom.value); - break; - case Compare_kind: - CALL(astfold_expr, expr_ty, node_->v.Compare.left); - CALL_SEQ(astfold_expr, expr, node_->v.Compare.comparators); - CALL(fold_compare, expr_ty, node_); - break; - case Call_kind: - CALL(astfold_expr, expr_ty, node_->v.Call.func); - CALL_SEQ(astfold_expr, expr, node_->v.Call.args); - CALL_SEQ(astfold_keyword, keyword, node_->v.Call.keywords); - break; - case FormattedValue_kind: - CALL(astfold_expr, expr_ty, node_->v.FormattedValue.value); - CALL_OPT(astfold_expr, expr_ty, node_->v.FormattedValue.format_spec); - break; - case JoinedStr_kind: - CALL_SEQ(astfold_expr, expr, node_->v.JoinedStr.values); - break; - case Attribute_kind: - CALL(astfold_expr, expr_ty, node_->v.Attribute.value); - break; - case Subscript_kind: - CALL(astfold_expr, expr_ty, node_->v.Subscript.value); - CALL(astfold_expr, expr_ty, node_->v.Subscript.slice); - CALL(fold_subscr, expr_ty, node_); - break; - case Starred_kind: - CALL(astfold_expr, expr_ty, node_->v.Starred.value); - break; - case Slice_kind: - CALL_OPT(astfold_expr, expr_ty, node_->v.Slice.lower); - CALL_OPT(astfold_expr, expr_ty, node_->v.Slice.upper); - CALL_OPT(astfold_expr, expr_ty, node_->v.Slice.step); - break; - case List_kind: - CALL_SEQ(astfold_expr, expr, node_->v.List.elts); - break; - case Tuple_kind: - CALL_SEQ(astfold_expr, expr, node_->v.Tuple.elts); - CALL(fold_tuple, expr_ty, node_); - break; - case Name_kind: - if (node_->v.Name.ctx == Load && - _PyUnicode_EqualToASCIIString(node_->v.Name.id, "__debug__")) { - state->recursion_depth--; - return make_const(node_, PyBool_FromLong(!state->optimize), ctx_); - } - break; - case NamedExpr_kind: - CALL(astfold_expr, expr_ty, node_->v.NamedExpr.value); - break; - case Constant_kind: - // Already a constant, nothing further to do - break; - // No default case, so the compiler will emit a warning if new expression - // kinds are added without being handled here - } - state->recursion_depth--; - return 1; -} - -static int -astfold_keyword(keyword_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) -{ - CALL(astfold_expr, expr_ty, node_->value); - return 1; -} - -static int -astfold_comprehension(comprehension_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) -{ - CALL(astfold_expr, expr_ty, node_->target); - CALL(astfold_expr, expr_ty, node_->iter); - CALL_SEQ(astfold_expr, expr, node_->ifs); - - CALL(fold_iter, expr_ty, node_->iter); - return 1; -} - -static int -astfold_arguments(arguments_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) -{ - CALL_SEQ(astfold_arg, arg, node_->posonlyargs); - CALL_SEQ(astfold_arg, arg, node_->args); - CALL_OPT(astfold_arg, arg_ty, node_->vararg); - CALL_SEQ(astfold_arg, arg, node_->kwonlyargs); - CALL_SEQ(astfold_expr, expr, node_->kw_defaults); - CALL_OPT(astfold_arg, arg_ty, node_->kwarg); - CALL_SEQ(astfold_expr, expr, node_->defaults); - return 1; -} - -static int -astfold_arg(arg_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) -{ - if (!(state->ff_features & CO_FUTURE_ANNOTATIONS)) { - CALL_OPT(astfold_expr, expr_ty, node_->annotation); - } - return 1; -} - -static int -astfold_stmt(stmt_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) -{ - if (++state->recursion_depth > state->recursion_limit) { - PyErr_SetString(PyExc_RecursionError, - "maximum recursion depth exceeded during compilation"); - return 0; - } - switch (node_->kind) { - case FunctionDef_kind: - CALL(astfold_arguments, arguments_ty, node_->v.FunctionDef.args); - CALL(astfold_body, asdl_seq, node_->v.FunctionDef.body); - CALL_SEQ(astfold_expr, expr, node_->v.FunctionDef.decorator_list); - if (!(state->ff_features & CO_FUTURE_ANNOTATIONS)) { - CALL_OPT(astfold_expr, expr_ty, node_->v.FunctionDef.returns); - } - break; - case AsyncFunctionDef_kind: - CALL(astfold_arguments, arguments_ty, node_->v.AsyncFunctionDef.args); - CALL(astfold_body, asdl_seq, node_->v.AsyncFunctionDef.body); - CALL_SEQ(astfold_expr, expr, node_->v.AsyncFunctionDef.decorator_list); - if (!(state->ff_features & CO_FUTURE_ANNOTATIONS)) { - CALL_OPT(astfold_expr, expr_ty, node_->v.AsyncFunctionDef.returns); - } - break; - case ClassDef_kind: - CALL_SEQ(astfold_expr, expr, node_->v.ClassDef.bases); - CALL_SEQ(astfold_keyword, keyword, node_->v.ClassDef.keywords); - CALL(astfold_body, asdl_seq, node_->v.ClassDef.body); - CALL_SEQ(astfold_expr, expr, node_->v.ClassDef.decorator_list); - break; - case Return_kind: - CALL_OPT(astfold_expr, expr_ty, node_->v.Return.value); - break; - case Delete_kind: - CALL_SEQ(astfold_expr, expr, node_->v.Delete.targets); - break; - case Assign_kind: - CALL_SEQ(astfold_expr, expr, node_->v.Assign.targets); - CALL(astfold_expr, expr_ty, node_->v.Assign.value); - break; - case AugAssign_kind: - CALL(astfold_expr, expr_ty, node_->v.AugAssign.target); - CALL(astfold_expr, expr_ty, node_->v.AugAssign.value); - break; - case AnnAssign_kind: - CALL(astfold_expr, expr_ty, node_->v.AnnAssign.target); - if (!(state->ff_features & CO_FUTURE_ANNOTATIONS)) { - CALL(astfold_expr, expr_ty, node_->v.AnnAssign.annotation); - } - CALL_OPT(astfold_expr, expr_ty, node_->v.AnnAssign.value); - break; - case For_kind: - CALL(astfold_expr, expr_ty, node_->v.For.target); - CALL(astfold_expr, expr_ty, node_->v.For.iter); - CALL_SEQ(astfold_stmt, stmt, node_->v.For.body); - CALL_SEQ(astfold_stmt, stmt, node_->v.For.orelse); - - CALL(fold_iter, expr_ty, node_->v.For.iter); - break; - case AsyncFor_kind: - CALL(astfold_expr, expr_ty, node_->v.AsyncFor.target); - CALL(astfold_expr, expr_ty, node_->v.AsyncFor.iter); - CALL_SEQ(astfold_stmt, stmt, node_->v.AsyncFor.body); - CALL_SEQ(astfold_stmt, stmt, node_->v.AsyncFor.orelse); - break; - case While_kind: - CALL(astfold_expr, expr_ty, node_->v.While.test); - CALL_SEQ(astfold_stmt, stmt, node_->v.While.body); - CALL_SEQ(astfold_stmt, stmt, node_->v.While.orelse); - break; - case If_kind: - CALL(astfold_expr, expr_ty, node_->v.If.test); - CALL_SEQ(astfold_stmt, stmt, node_->v.If.body); - CALL_SEQ(astfold_stmt, stmt, node_->v.If.orelse); - break; - case With_kind: - CALL_SEQ(astfold_withitem, withitem, node_->v.With.items); - CALL_SEQ(astfold_stmt, stmt, node_->v.With.body); - break; - case AsyncWith_kind: - CALL_SEQ(astfold_withitem, withitem, node_->v.AsyncWith.items); - CALL_SEQ(astfold_stmt, stmt, node_->v.AsyncWith.body); - break; - case Raise_kind: - CALL_OPT(astfold_expr, expr_ty, node_->v.Raise.exc); - CALL_OPT(astfold_expr, expr_ty, node_->v.Raise.cause); - break; - case Try_kind: - CALL_SEQ(astfold_stmt, stmt, node_->v.Try.body); - CALL_SEQ(astfold_excepthandler, excepthandler, node_->v.Try.handlers); - CALL_SEQ(astfold_stmt, stmt, node_->v.Try.orelse); - CALL_SEQ(astfold_stmt, stmt, node_->v.Try.finalbody); - break; - case Assert_kind: - CALL(astfold_expr, expr_ty, node_->v.Assert.test); - CALL_OPT(astfold_expr, expr_ty, node_->v.Assert.msg); - break; - case Expr_kind: - CALL(astfold_expr, expr_ty, node_->v.Expr.value); - break; - case Match_kind: - CALL(astfold_expr, expr_ty, node_->v.Match.subject); - CALL_SEQ(astfold_match_case, match_case, node_->v.Match.cases); - break; - // The following statements don't contain any subexpressions to be folded - case Import_kind: - case ImportFrom_kind: - case Global_kind: - case Nonlocal_kind: - case Pass_kind: - case Break_kind: - case Continue_kind: - break; - // No default case, so the compiler will emit a warning if new statement - // kinds are added without being handled here - } - state->recursion_depth--; - return 1; -} - -static int -astfold_excepthandler(excepthandler_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) -{ - switch (node_->kind) { - case ExceptHandler_kind: - CALL_OPT(astfold_expr, expr_ty, node_->v.ExceptHandler.type); - CALL_SEQ(astfold_stmt, stmt, node_->v.ExceptHandler.body); - break; - // No default case, so the compiler will emit a warning if new handler - // kinds are added without being handled here - } - return 1; -} - -static int -astfold_withitem(withitem_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) -{ - CALL(astfold_expr, expr_ty, node_->context_expr); - CALL_OPT(astfold_expr, expr_ty, node_->optional_vars); - return 1; -} - -static int -astfold_pattern(pattern_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) -{ - // Currently, this is really only used to form complex/negative numeric - // constants in MatchValue and MatchMapping nodes - // We still recurse into all subexpressions and subpatterns anyway - if (++state->recursion_depth > state->recursion_limit) { - PyErr_SetString(PyExc_RecursionError, - "maximum recursion depth exceeded during compilation"); - return 0; - } - switch (node_->kind) { - case MatchValue_kind: - CALL(astfold_expr, expr_ty, node_->v.MatchValue.value); - break; - case MatchSingleton_kind: - break; - case MatchSequence_kind: - CALL_SEQ(astfold_pattern, pattern, node_->v.MatchSequence.patterns); - break; - case MatchMapping_kind: - CALL_SEQ(astfold_expr, expr, node_->v.MatchMapping.keys); - CALL_SEQ(astfold_pattern, pattern, node_->v.MatchMapping.patterns); - break; - case MatchClass_kind: - CALL(astfold_expr, expr_ty, node_->v.MatchClass.cls); - CALL_SEQ(astfold_pattern, pattern, node_->v.MatchClass.patterns); - CALL_SEQ(astfold_pattern, pattern, node_->v.MatchClass.kwd_patterns); - break; - case MatchStar_kind: - break; - case MatchAs_kind: - if (node_->v.MatchAs.pattern) { - CALL(astfold_pattern, pattern_ty, node_->v.MatchAs.pattern); - } - break; - case MatchOr_kind: - CALL_SEQ(astfold_pattern, pattern, node_->v.MatchOr.patterns); - break; - // No default case, so the compiler will emit a warning if new pattern - // kinds are added without being handled here - } - state->recursion_depth--; - return 1; -} - -static int -astfold_match_case(match_case_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) -{ - CALL(astfold_pattern, expr_ty, node_->pattern); - CALL_OPT(astfold_expr, expr_ty, node_->guard); - CALL_SEQ(astfold_stmt, stmt, node_->body); - return 1; -} - -#undef CALL -#undef CALL_OPT -#undef CALL_SEQ -#undef CALL_INT_SEQ - -/* See comments in symtable.c. */ -#define COMPILER_STACK_FRAME_SCALE 3 - -int -_PyAST_Optimize(mod_ty mod, PyArena *arena, _PyASTOptimizeState *state) -{ - PyThreadState *tstate; - int recursion_limit = Py_GetRecursionLimit(); - int starting_recursion_depth; - - /* Setup recursion depth check counters */ - tstate = _PyThreadState_GET(); - if (!tstate) { - return 0; - } - /* Be careful here to prevent overflow. */ - starting_recursion_depth = (tstate->recursion_depth < INT_MAX / COMPILER_STACK_FRAME_SCALE) ? - tstate->recursion_depth * COMPILER_STACK_FRAME_SCALE : tstate->recursion_depth; - state->recursion_depth = starting_recursion_depth; - state->recursion_limit = (recursion_limit < INT_MAX / COMPILER_STACK_FRAME_SCALE) ? - recursion_limit * COMPILER_STACK_FRAME_SCALE : recursion_limit; - - int ret = astfold_mod(mod, arena, state); - assert(ret || PyErr_Occurred()); - - /* Check that the recursion depth counting balanced correctly */ - if (ret && state->recursion_depth != starting_recursion_depth) { - PyErr_Format(PyExc_SystemError, - "AST optimizer recursion depth mismatch (before=%d, after=%d)", - starting_recursion_depth, state->recursion_depth); - return 0; - } - - return ret; -} diff --git a/contrib/tools/python3/src/Python/ast_unparse.c b/contrib/tools/python3/src/Python/ast_unparse.c deleted file mode 100644 index 126e9047d58..00000000000 --- a/contrib/tools/python3/src/Python/ast_unparse.c +++ /dev/null @@ -1,977 +0,0 @@ -#include "Python.h" -#include "pycore_ast.h" // expr_ty -#include <float.h> // DBL_MAX_10_EXP -#include <stdbool.h> - -/* This limited unparser is used to convert annotations back to strings - * during compilation rather than being a full AST unparser. - * See ast.unparse for a full unparser (written in Python) - */ - -static PyObject *_str_open_br; -static PyObject *_str_dbl_open_br; -static PyObject *_str_close_br; -static PyObject *_str_dbl_close_br; -static PyObject *_str_inf; -static PyObject *_str_replace_inf; - -/* Forward declarations for recursion via helper functions. */ -static PyObject * -expr_as_unicode(expr_ty e, int level); -static int -append_ast_expr(_PyUnicodeWriter *writer, expr_ty e, int level); -static int -append_joinedstr(_PyUnicodeWriter *writer, expr_ty e, bool is_format_spec); -static int -append_formattedvalue(_PyUnicodeWriter *writer, expr_ty e); -static int -append_ast_slice(_PyUnicodeWriter *writer, expr_ty e); - -static int -append_charp(_PyUnicodeWriter *writer, const char *charp) -{ - return _PyUnicodeWriter_WriteASCIIString(writer, charp, -1); -} - -#define APPEND_STR_FINISH(str) do { \ - return append_charp(writer, (str)); \ - } while (0) - -#define APPEND_STR(str) do { \ - if (-1 == append_charp(writer, (str))) { \ - return -1; \ - } \ - } while (0) - -#define APPEND_STR_IF(cond, str) do { \ - if ((cond) && -1 == append_charp(writer, (str))) { \ - return -1; \ - } \ - } while (0) - -#define APPEND_STR_IF_NOT_FIRST(str) do { \ - APPEND_STR_IF(!first, (str)); \ - first = false; \ - } while (0) - -#define APPEND_EXPR(expr, pr) do { \ - if (-1 == append_ast_expr(writer, (expr), (pr))) { \ - return -1; \ - } \ - } while (0) - -#define APPEND(type, value) do { \ - if (-1 == append_ast_ ## type(writer, (value))) { \ - return -1; \ - } \ - } while (0) - -static int -append_repr(_PyUnicodeWriter *writer, PyObject *obj) -{ - PyObject *repr = PyObject_Repr(obj); - - if (!repr) { - return -1; - } - - if ((PyFloat_CheckExact(obj) && Py_IS_INFINITY(PyFloat_AS_DOUBLE(obj))) || - PyComplex_CheckExact(obj)) - { - PyObject *new_repr = PyUnicode_Replace( - repr, - _str_inf, - _str_replace_inf, - -1 - ); - Py_DECREF(repr); - if (!new_repr) { - return -1; - } - repr = new_repr; - } - int ret = _PyUnicodeWriter_WriteStr(writer, repr); - Py_DECREF(repr); - return ret; -} - -/* Priority levels */ - -enum { - PR_TUPLE, - PR_TEST, /* 'if'-'else', 'lambda' */ - PR_OR, /* 'or' */ - PR_AND, /* 'and' */ - PR_NOT, /* 'not' */ - PR_CMP, /* '<', '>', '==', '>=', '<=', '!=', - 'in', 'not in', 'is', 'is not' */ - PR_EXPR, - PR_BOR = PR_EXPR, /* '|' */ - PR_BXOR, /* '^' */ - PR_BAND, /* '&' */ - PR_SHIFT, /* '<<', '>>' */ - PR_ARITH, /* '+', '-' */ - PR_TERM, /* '*', '@', '/', '%', '//' */ - PR_FACTOR, /* unary '+', '-', '~' */ - PR_POWER, /* '**' */ - PR_AWAIT, /* 'await' */ - PR_ATOM, -}; - -static int -append_ast_boolop(_PyUnicodeWriter *writer, expr_ty e, int level) -{ - Py_ssize_t i, value_count; - asdl_expr_seq *values; - const char *op = (e->v.BoolOp.op == And) ? " and " : " or "; - int pr = (e->v.BoolOp.op == And) ? PR_AND : PR_OR; - - APPEND_STR_IF(level > pr, "("); - - values = e->v.BoolOp.values; - value_count = asdl_seq_LEN(values); - - for (i = 0; i < value_count; ++i) { - APPEND_STR_IF(i > 0, op); - APPEND_EXPR((expr_ty)asdl_seq_GET(values, i), pr + 1); - } - - APPEND_STR_IF(level > pr, ")"); - return 0; -} - -static int -append_ast_binop(_PyUnicodeWriter *writer, expr_ty e, int level) -{ - const char *op; - int pr; - bool rassoc = false; /* is right-associative? */ - - switch (e->v.BinOp.op) { - case Add: op = " + "; pr = PR_ARITH; break; - case Sub: op = " - "; pr = PR_ARITH; break; - case Mult: op = " * "; pr = PR_TERM; break; - case MatMult: op = " @ "; pr = PR_TERM; break; - case Div: op = " / "; pr = PR_TERM; break; - case Mod: op = " % "; pr = PR_TERM; break; - case LShift: op = " << "; pr = PR_SHIFT; break; - case RShift: op = " >> "; pr = PR_SHIFT; break; - case BitOr: op = " | "; pr = PR_BOR; break; - case BitXor: op = " ^ "; pr = PR_BXOR; break; - case BitAnd: op = " & "; pr = PR_BAND; break; - case FloorDiv: op = " // "; pr = PR_TERM; break; - case Pow: op = " ** "; pr = PR_POWER; rassoc = true; break; - default: - PyErr_SetString(PyExc_SystemError, - "unknown binary operator"); - return -1; - } - - APPEND_STR_IF(level > pr, "("); - APPEND_EXPR(e->v.BinOp.left, pr + rassoc); - APPEND_STR(op); - APPEND_EXPR(e->v.BinOp.right, pr + !rassoc); - APPEND_STR_IF(level > pr, ")"); - return 0; -} - -static int -append_ast_unaryop(_PyUnicodeWriter *writer, expr_ty e, int level) -{ - const char *op; - int pr; - - switch (e->v.UnaryOp.op) { - case Invert: op = "~"; pr = PR_FACTOR; break; - case Not: op = "not "; pr = PR_NOT; break; - case UAdd: op = "+"; pr = PR_FACTOR; break; - case USub: op = "-"; pr = PR_FACTOR; break; - default: - PyErr_SetString(PyExc_SystemError, - "unknown unary operator"); - return -1; - } - - APPEND_STR_IF(level > pr, "("); - APPEND_STR(op); - APPEND_EXPR(e->v.UnaryOp.operand, pr); - APPEND_STR_IF(level > pr, ")"); - return 0; -} - -static int -append_ast_arg(_PyUnicodeWriter *writer, arg_ty arg) -{ - if (-1 == _PyUnicodeWriter_WriteStr(writer, arg->arg)) { - return -1; - } - if (arg->annotation) { - APPEND_STR(": "); - APPEND_EXPR(arg->annotation, PR_TEST); - } - return 0; -} - -static int -append_ast_args(_PyUnicodeWriter *writer, arguments_ty args) -{ - bool first; - Py_ssize_t i, di, arg_count, posonlyarg_count, default_count; - - first = true; - - /* positional-only and positional arguments with defaults */ - posonlyarg_count = asdl_seq_LEN(args->posonlyargs); - arg_count = asdl_seq_LEN(args->args); - default_count = asdl_seq_LEN(args->defaults); - for (i = 0; i < posonlyarg_count + arg_count; i++) { - APPEND_STR_IF_NOT_FIRST(", "); - if (i < posonlyarg_count){ - APPEND(arg, (arg_ty)asdl_seq_GET(args->posonlyargs, i)); - } else { - APPEND(arg, (arg_ty)asdl_seq_GET(args->args, i-posonlyarg_count)); - } - - di = i - posonlyarg_count - arg_count + default_count; - if (di >= 0) { - APPEND_STR("="); - APPEND_EXPR((expr_ty)asdl_seq_GET(args->defaults, di), PR_TEST); - } - if (posonlyarg_count && i + 1 == posonlyarg_count) { - APPEND_STR(", /"); - } - } - - /* vararg, or bare '*' if no varargs but keyword-only arguments present */ - if (args->vararg || asdl_seq_LEN(args->kwonlyargs)) { - APPEND_STR_IF_NOT_FIRST(", "); - APPEND_STR("*"); - if (args->vararg) { - APPEND(arg, args->vararg); - } - } - - /* keyword-only arguments */ - arg_count = asdl_seq_LEN(args->kwonlyargs); - default_count = asdl_seq_LEN(args->kw_defaults); - for (i = 0; i < arg_count; i++) { - APPEND_STR_IF_NOT_FIRST(", "); - APPEND(arg, (arg_ty)asdl_seq_GET(args->kwonlyargs, i)); - - di = i - arg_count + default_count; - if (di >= 0) { - expr_ty default_ = (expr_ty)asdl_seq_GET(args->kw_defaults, di); - if (default_) { - APPEND_STR("="); - APPEND_EXPR(default_, PR_TEST); - } - } - } - - /* **kwargs */ - if (args->kwarg) { - APPEND_STR_IF_NOT_FIRST(", "); - APPEND_STR("**"); - APPEND(arg, args->kwarg); - } - - return 0; -} - -static int -append_ast_lambda(_PyUnicodeWriter *writer, expr_ty e, int level) -{ - APPEND_STR_IF(level > PR_TEST, "("); - Py_ssize_t n_positional = (asdl_seq_LEN(e->v.Lambda.args->args) + - asdl_seq_LEN(e->v.Lambda.args->posonlyargs)); - APPEND_STR(n_positional ? "lambda " : "lambda"); - APPEND(args, e->v.Lambda.args); - APPEND_STR(": "); - APPEND_EXPR(e->v.Lambda.body, PR_TEST); - APPEND_STR_IF(level > PR_TEST, ")"); - return 0; -} - -static int -append_ast_ifexp(_PyUnicodeWriter *writer, expr_ty e, int level) -{ - APPEND_STR_IF(level > PR_TEST, "("); - APPEND_EXPR(e->v.IfExp.body, PR_TEST + 1); - APPEND_STR(" if "); - APPEND_EXPR(e->v.IfExp.test, PR_TEST + 1); - APPEND_STR(" else "); - APPEND_EXPR(e->v.IfExp.orelse, PR_TEST); - APPEND_STR_IF(level > PR_TEST, ")"); - return 0; -} - -static int -append_ast_dict(_PyUnicodeWriter *writer, expr_ty e) -{ - Py_ssize_t i, value_count; - expr_ty key_node; - - APPEND_STR("{"); - value_count = asdl_seq_LEN(e->v.Dict.values); - - for (i = 0; i < value_count; i++) { - APPEND_STR_IF(i > 0, ", "); - key_node = (expr_ty)asdl_seq_GET(e->v.Dict.keys, i); - if (key_node != NULL) { - APPEND_EXPR(key_node, PR_TEST); - APPEND_STR(": "); - APPEND_EXPR((expr_ty)asdl_seq_GET(e->v.Dict.values, i), PR_TEST); - } - else { - APPEND_STR("**"); - APPEND_EXPR((expr_ty)asdl_seq_GET(e->v.Dict.values, i), PR_EXPR); - } - } - - APPEND_STR_FINISH("}"); -} - -static int -append_ast_set(_PyUnicodeWriter *writer, expr_ty e) -{ - Py_ssize_t i, elem_count; - - APPEND_STR("{"); - elem_count = asdl_seq_LEN(e->v.Set.elts); - for (i = 0; i < elem_count; i++) { - APPEND_STR_IF(i > 0, ", "); - APPEND_EXPR((expr_ty)asdl_seq_GET(e->v.Set.elts, i), PR_TEST); - } - - APPEND_STR_FINISH("}"); -} - -static int -append_ast_list(_PyUnicodeWriter *writer, expr_ty e) -{ - Py_ssize_t i, elem_count; - - APPEND_STR("["); - elem_count = asdl_seq_LEN(e->v.List.elts); - for (i = 0; i < elem_count; i++) { - APPEND_STR_IF(i > 0, ", "); - APPEND_EXPR((expr_ty)asdl_seq_GET(e->v.List.elts, i), PR_TEST); - } - - APPEND_STR_FINISH("]"); -} - -static int -append_ast_tuple(_PyUnicodeWriter *writer, expr_ty e, int level) -{ - Py_ssize_t i, elem_count; - - elem_count = asdl_seq_LEN(e->v.Tuple.elts); - - if (elem_count == 0) { - APPEND_STR_FINISH("()"); - } - - APPEND_STR_IF(level > PR_TUPLE, "("); - - for (i = 0; i < elem_count; i++) { - APPEND_STR_IF(i > 0, ", "); - APPEND_EXPR((expr_ty)asdl_seq_GET(e->v.Tuple.elts, i), PR_TEST); - } - - APPEND_STR_IF(elem_count == 1, ","); - APPEND_STR_IF(level > PR_TUPLE, ")"); - return 0; -} - -static int -append_ast_comprehension(_PyUnicodeWriter *writer, comprehension_ty gen) -{ - Py_ssize_t i, if_count; - - APPEND_STR(gen->is_async ? " async for " : " for "); - APPEND_EXPR(gen->target, PR_TUPLE); - APPEND_STR(" in "); - APPEND_EXPR(gen->iter, PR_TEST + 1); - - if_count = asdl_seq_LEN(gen->ifs); - for (i = 0; i < if_count; i++) { - APPEND_STR(" if "); - APPEND_EXPR((expr_ty)asdl_seq_GET(gen->ifs, i), PR_TEST + 1); - } - return 0; -} - -static int -append_ast_comprehensions(_PyUnicodeWriter *writer, asdl_comprehension_seq *comprehensions) -{ - Py_ssize_t i, gen_count; - gen_count = asdl_seq_LEN(comprehensions); - - for (i = 0; i < gen_count; i++) { - APPEND(comprehension, (comprehension_ty)asdl_seq_GET(comprehensions, i)); - } - - return 0; -} - -static int -append_ast_genexp(_PyUnicodeWriter *writer, expr_ty e) -{ - APPEND_STR("("); - APPEND_EXPR(e->v.GeneratorExp.elt, PR_TEST); - APPEND(comprehensions, e->v.GeneratorExp.generators); - APPEND_STR_FINISH(")"); -} - -static int -append_ast_listcomp(_PyUnicodeWriter *writer, expr_ty e) -{ - APPEND_STR("["); - APPEND_EXPR(e->v.ListComp.elt, PR_TEST); - APPEND(comprehensions, e->v.ListComp.generators); - APPEND_STR_FINISH("]"); -} - -static int -append_ast_setcomp(_PyUnicodeWriter *writer, expr_ty e) -{ - APPEND_STR("{"); - APPEND_EXPR(e->v.SetComp.elt, PR_TEST); - APPEND(comprehensions, e->v.SetComp.generators); - APPEND_STR_FINISH("}"); -} - -static int -append_ast_dictcomp(_PyUnicodeWriter *writer, expr_ty e) -{ - APPEND_STR("{"); - APPEND_EXPR(e->v.DictComp.key, PR_TEST); - APPEND_STR(": "); - APPEND_EXPR(e->v.DictComp.value, PR_TEST); - APPEND(comprehensions, e->v.DictComp.generators); - APPEND_STR_FINISH("}"); -} - -static int -append_ast_compare(_PyUnicodeWriter *writer, expr_ty e, int level) -{ - const char *op; - Py_ssize_t i, comparator_count; - asdl_expr_seq *comparators; - asdl_int_seq *ops; - - APPEND_STR_IF(level > PR_CMP, "("); - - comparators = e->v.Compare.comparators; - ops = e->v.Compare.ops; - comparator_count = asdl_seq_LEN(comparators); - assert(comparator_count > 0); - assert(comparator_count == asdl_seq_LEN(ops)); - - APPEND_EXPR(e->v.Compare.left, PR_CMP + 1); - - for (i = 0; i < comparator_count; i++) { - switch ((cmpop_ty)asdl_seq_GET(ops, i)) { - case Eq: - op = " == "; - break; - case NotEq: - op = " != "; - break; - case Lt: - op = " < "; - break; - case LtE: - op = " <= "; - break; - case Gt: - op = " > "; - break; - case GtE: - op = " >= "; - break; - case Is: - op = " is "; - break; - case IsNot: - op = " is not "; - break; - case In: - op = " in "; - break; - case NotIn: - op = " not in "; - break; - default: - PyErr_SetString(PyExc_SystemError, - "unexpected comparison kind"); - return -1; - } - - APPEND_STR(op); - APPEND_EXPR((expr_ty)asdl_seq_GET(comparators, i), PR_CMP + 1); - } - - APPEND_STR_IF(level > PR_CMP, ")"); - return 0; -} - -static int -append_ast_keyword(_PyUnicodeWriter *writer, keyword_ty kw) -{ - if (kw->arg == NULL) { - APPEND_STR("**"); - } - else { - if (-1 == _PyUnicodeWriter_WriteStr(writer, kw->arg)) { - return -1; - } - - APPEND_STR("="); - } - - APPEND_EXPR(kw->value, PR_TEST); - return 0; -} - -static int -append_ast_call(_PyUnicodeWriter *writer, expr_ty e) -{ - bool first; - Py_ssize_t i, arg_count, kw_count; - expr_ty expr; - - APPEND_EXPR(e->v.Call.func, PR_ATOM); - - arg_count = asdl_seq_LEN(e->v.Call.args); - kw_count = asdl_seq_LEN(e->v.Call.keywords); - if (arg_count == 1 && kw_count == 0) { - expr = (expr_ty)asdl_seq_GET(e->v.Call.args, 0); - if (expr->kind == GeneratorExp_kind) { - /* Special case: a single generator expression. */ - return append_ast_genexp(writer, expr); - } - } - - APPEND_STR("("); - - first = true; - for (i = 0; i < arg_count; i++) { - APPEND_STR_IF_NOT_FIRST(", "); - APPEND_EXPR((expr_ty)asdl_seq_GET(e->v.Call.args, i), PR_TEST); - } - - for (i = 0; i < kw_count; i++) { - APPEND_STR_IF_NOT_FIRST(", "); - APPEND(keyword, (keyword_ty)asdl_seq_GET(e->v.Call.keywords, i)); - } - - APPEND_STR_FINISH(")"); -} - -static PyObject * -escape_braces(PyObject *orig) -{ - PyObject *temp; - PyObject *result; - temp = PyUnicode_Replace(orig, _str_open_br, _str_dbl_open_br, -1); - if (!temp) { - return NULL; - } - result = PyUnicode_Replace(temp, _str_close_br, _str_dbl_close_br, -1); - Py_DECREF(temp); - return result; -} - -static int -append_fstring_unicode(_PyUnicodeWriter *writer, PyObject *unicode) -{ - PyObject *escaped; - int result = -1; - escaped = escape_braces(unicode); - if (escaped) { - result = _PyUnicodeWriter_WriteStr(writer, escaped); - Py_DECREF(escaped); - } - return result; -} - -static int -append_fstring_element(_PyUnicodeWriter *writer, expr_ty e, bool is_format_spec) -{ - switch (e->kind) { - case Constant_kind: - return append_fstring_unicode(writer, e->v.Constant.value); - case JoinedStr_kind: - return append_joinedstr(writer, e, is_format_spec); - case FormattedValue_kind: - return append_formattedvalue(writer, e); - default: - PyErr_SetString(PyExc_SystemError, - "unknown expression kind inside f-string"); - return -1; - } -} - -/* Build body separately to enable wrapping the entire stream of Strs, - Constants and FormattedValues in one opening and one closing quote. */ -static PyObject * -build_fstring_body(asdl_expr_seq *values, bool is_format_spec) -{ - Py_ssize_t i, value_count; - _PyUnicodeWriter body_writer; - _PyUnicodeWriter_Init(&body_writer); - body_writer.min_length = 256; - body_writer.overallocate = 1; - - value_count = asdl_seq_LEN(values); - for (i = 0; i < value_count; ++i) { - if (-1 == append_fstring_element(&body_writer, - (expr_ty)asdl_seq_GET(values, i), - is_format_spec - )) { - _PyUnicodeWriter_Dealloc(&body_writer); - return NULL; - } - } - - return _PyUnicodeWriter_Finish(&body_writer); -} - -static int -append_joinedstr(_PyUnicodeWriter *writer, expr_ty e, bool is_format_spec) -{ - int result = -1; - PyObject *body = build_fstring_body(e->v.JoinedStr.values, is_format_spec); - if (!body) { - return -1; - } - - if (!is_format_spec) { - if (-1 != append_charp(writer, "f") && - -1 != append_repr(writer, body)) - { - result = 0; - } - } - else { - result = _PyUnicodeWriter_WriteStr(writer, body); - } - Py_DECREF(body); - return result; -} - -static int -append_formattedvalue(_PyUnicodeWriter *writer, expr_ty e) -{ - const char *conversion; - const char *outer_brace = "{"; - /* Grammar allows PR_TUPLE, but use >PR_TEST for adding parenthesis - around a lambda with ':' */ - PyObject *temp_fv_str = expr_as_unicode(e->v.FormattedValue.value, PR_TEST + 1); - if (!temp_fv_str) { - return -1; - } - if (PyUnicode_Find(temp_fv_str, _str_open_br, 0, 1, 1) == 0) { - /* Expression starts with a brace, split it with a space from the outer - one. */ - outer_brace = "{ "; - } - if (-1 == append_charp(writer, outer_brace)) { - Py_DECREF(temp_fv_str); - return -1; - } - if (-1 == _PyUnicodeWriter_WriteStr(writer, temp_fv_str)) { - Py_DECREF(temp_fv_str); - return -1; - } - Py_DECREF(temp_fv_str); - - if (e->v.FormattedValue.conversion > 0) { - switch (e->v.FormattedValue.conversion) { - case 'a': - conversion = "!a"; - break; - case 'r': - conversion = "!r"; - break; - case 's': - conversion = "!s"; - break; - default: - PyErr_SetString(PyExc_SystemError, - "unknown f-value conversion kind"); - return -1; - } - APPEND_STR(conversion); - } - if (e->v.FormattedValue.format_spec) { - if (-1 == _PyUnicodeWriter_WriteASCIIString(writer, ":", 1) || - -1 == append_fstring_element(writer, - e->v.FormattedValue.format_spec, - true - )) - { - return -1; - } - } - - APPEND_STR_FINISH("}"); -} - -static int -append_ast_constant(_PyUnicodeWriter *writer, PyObject *constant) -{ - if (PyTuple_CheckExact(constant)) { - Py_ssize_t i, elem_count; - - elem_count = PyTuple_GET_SIZE(constant); - APPEND_STR("("); - for (i = 0; i < elem_count; i++) { - APPEND_STR_IF(i > 0, ", "); - if (append_ast_constant(writer, PyTuple_GET_ITEM(constant, i)) < 0) { - return -1; - } - } - - APPEND_STR_IF(elem_count == 1, ","); - APPEND_STR(")"); - return 0; - } - return append_repr(writer, constant); -} - -static int -append_ast_attribute(_PyUnicodeWriter *writer, expr_ty e) -{ - const char *period; - expr_ty v = e->v.Attribute.value; - APPEND_EXPR(v, PR_ATOM); - - /* Special case: integers require a space for attribute access to be - unambiguous. */ - if (v->kind == Constant_kind && PyLong_CheckExact(v->v.Constant.value)) { - period = " ."; - } - else { - period = "."; - } - APPEND_STR(period); - - return _PyUnicodeWriter_WriteStr(writer, e->v.Attribute.attr); -} - -static int -append_ast_slice(_PyUnicodeWriter *writer, expr_ty e) -{ - if (e->v.Slice.lower) { - APPEND_EXPR(e->v.Slice.lower, PR_TEST); - } - - APPEND_STR(":"); - - if (e->v.Slice.upper) { - APPEND_EXPR(e->v.Slice.upper, PR_TEST); - } - - if (e->v.Slice.step) { - APPEND_STR(":"); - APPEND_EXPR(e->v.Slice.step, PR_TEST); - } - return 0; -} - -static int -append_ast_subscript(_PyUnicodeWriter *writer, expr_ty e) -{ - APPEND_EXPR(e->v.Subscript.value, PR_ATOM); - int level = PR_TUPLE; - expr_ty slice = e->v.Subscript.slice; - if (slice->kind == Tuple_kind) { - for (Py_ssize_t i = 0; i < asdl_seq_LEN(slice->v.Tuple.elts); i++) { - expr_ty element = asdl_seq_GET(slice->v.Tuple.elts, i); - if (element->kind == Starred_kind) { - ++level; - break; - } - } - } - APPEND_STR("["); - APPEND_EXPR(e->v.Subscript.slice, level); - APPEND_STR_FINISH("]"); -} - -static int -append_ast_starred(_PyUnicodeWriter *writer, expr_ty e) -{ - APPEND_STR("*"); - APPEND_EXPR(e->v.Starred.value, PR_EXPR); - return 0; -} - -static int -append_ast_yield(_PyUnicodeWriter *writer, expr_ty e) -{ - if (!e->v.Yield.value) { - APPEND_STR_FINISH("(yield)"); - } - - APPEND_STR("(yield "); - APPEND_EXPR(e->v.Yield.value, PR_TEST); - APPEND_STR_FINISH(")"); -} - -static int -append_ast_yield_from(_PyUnicodeWriter *writer, expr_ty e) -{ - APPEND_STR("(yield from "); - APPEND_EXPR(e->v.YieldFrom.value, PR_TEST); - APPEND_STR_FINISH(")"); -} - -static int -append_ast_await(_PyUnicodeWriter *writer, expr_ty e, int level) -{ - APPEND_STR_IF(level > PR_AWAIT, "("); - APPEND_STR("await "); - APPEND_EXPR(e->v.Await.value, PR_ATOM); - APPEND_STR_IF(level > PR_AWAIT, ")"); - return 0; -} - -static int -append_named_expr(_PyUnicodeWriter *writer, expr_ty e, int level) -{ - APPEND_STR_IF(level > PR_TUPLE, "("); - APPEND_EXPR(e->v.NamedExpr.target, PR_ATOM); - APPEND_STR(" := "); - APPEND_EXPR(e->v.NamedExpr.value, PR_ATOM); - APPEND_STR_IF(level > PR_TUPLE, ")"); - return 0; -} - -static int -append_ast_expr(_PyUnicodeWriter *writer, expr_ty e, int level) -{ - switch (e->kind) { - case BoolOp_kind: - return append_ast_boolop(writer, e, level); - case BinOp_kind: - return append_ast_binop(writer, e, level); - case UnaryOp_kind: - return append_ast_unaryop(writer, e, level); - case Lambda_kind: - return append_ast_lambda(writer, e, level); - case IfExp_kind: - return append_ast_ifexp(writer, e, level); - case Dict_kind: - return append_ast_dict(writer, e); - case Set_kind: - return append_ast_set(writer, e); - case GeneratorExp_kind: - return append_ast_genexp(writer, e); - case ListComp_kind: - return append_ast_listcomp(writer, e); - case SetComp_kind: - return append_ast_setcomp(writer, e); - case DictComp_kind: - return append_ast_dictcomp(writer, e); - case Yield_kind: - return append_ast_yield(writer, e); - case YieldFrom_kind: - return append_ast_yield_from(writer, e); - case Await_kind: - return append_ast_await(writer, e, level); - case Compare_kind: - return append_ast_compare(writer, e, level); - case Call_kind: - return append_ast_call(writer, e); - case Constant_kind: - if (e->v.Constant.value == Py_Ellipsis) { - APPEND_STR_FINISH("..."); - } - if (e->v.Constant.kind != NULL - && -1 == _PyUnicodeWriter_WriteStr(writer, e->v.Constant.kind)) { - return -1; - } - return append_ast_constant(writer, e->v.Constant.value); - case JoinedStr_kind: - return append_joinedstr(writer, e, false); - case FormattedValue_kind: - return append_formattedvalue(writer, e); - /* The following exprs can be assignment targets. */ - case Attribute_kind: - return append_ast_attribute(writer, e); - case Subscript_kind: - return append_ast_subscript(writer, e); - case Starred_kind: - return append_ast_starred(writer, e); - case Slice_kind: - return append_ast_slice(writer, e); - case Name_kind: - return _PyUnicodeWriter_WriteStr(writer, e->v.Name.id); - case List_kind: - return append_ast_list(writer, e); - case Tuple_kind: - return append_ast_tuple(writer, e, level); - case NamedExpr_kind: - return append_named_expr(writer, e, level); - // No default so compiler emits a warning for unhandled cases - } - PyErr_SetString(PyExc_SystemError, - "unknown expression kind"); - return -1; -} - -static int -maybe_init_static_strings(void) -{ - if (!_str_open_br && - !(_str_open_br = PyUnicode_InternFromString("{"))) { - return -1; - } - if (!_str_dbl_open_br && - !(_str_dbl_open_br = PyUnicode_InternFromString("{{"))) { - return -1; - } - if (!_str_close_br && - !(_str_close_br = PyUnicode_InternFromString("}"))) { - return -1; - } - if (!_str_dbl_close_br && - !(_str_dbl_close_br = PyUnicode_InternFromString("}}"))) { - return -1; - } - if (!_str_inf && - !(_str_inf = PyUnicode_FromString("inf"))) { - return -1; - } - if (!_str_replace_inf && - !(_str_replace_inf = PyUnicode_FromFormat("1e%d", 1 + DBL_MAX_10_EXP))) { - return -1; - } - return 0; -} - -static PyObject * -expr_as_unicode(expr_ty e, int level) -{ - _PyUnicodeWriter writer; - _PyUnicodeWriter_Init(&writer); - writer.min_length = 256; - writer.overallocate = 1; - if (-1 == maybe_init_static_strings() || - -1 == append_ast_expr(&writer, e, level)) - { - _PyUnicodeWriter_Dealloc(&writer); - return NULL; - } - return _PyUnicodeWriter_Finish(&writer); -} - -PyObject * -_PyAST_ExprAsUnicode(expr_ty e) -{ - return expr_as_unicode(e, PR_TEST); -} diff --git a/contrib/tools/python3/src/Python/bltinmodule.c b/contrib/tools/python3/src/Python/bltinmodule.c deleted file mode 100644 index b0162e5e872..00000000000 --- a/contrib/tools/python3/src/Python/bltinmodule.c +++ /dev/null @@ -1,3049 +0,0 @@ -/* Built-in functions */ - -#include "Python.h" -#include <ctype.h> -#include "pycore_ast.h" // _PyAST_Validate() -#include "pycore_compile.h" // _PyAST_Compile() -#include "pycore_object.h" // _Py_AddToAllObjects() -#include "pycore_pyerrors.h" // _PyErr_NoMemory() -#include "pycore_pystate.h" // _PyThreadState_GET() -#include "pycore_tuple.h" // _PyTuple_FromArray() -#include "pycore_ceval.h" // _PyEval_Vector() - -_Py_IDENTIFIER(__builtins__); -_Py_IDENTIFIER(__dict__); -_Py_IDENTIFIER(__prepare__); -_Py_IDENTIFIER(__round__); -_Py_IDENTIFIER(__mro_entries__); -_Py_IDENTIFIER(encoding); -_Py_IDENTIFIER(errors); -_Py_IDENTIFIER(fileno); -_Py_IDENTIFIER(flush); -_Py_IDENTIFIER(metaclass); -_Py_IDENTIFIER(sort); -_Py_IDENTIFIER(stdin); -_Py_IDENTIFIER(stdout); -_Py_IDENTIFIER(stderr); - -#include "clinic/bltinmodule.c.h" - -static PyObject* -update_bases(PyObject *bases, PyObject *const *args, Py_ssize_t nargs) -{ - Py_ssize_t i, j; - PyObject *base, *meth, *new_base, *result, *new_bases = NULL; - assert(PyTuple_Check(bases)); - - for (i = 0; i < nargs; i++) { - base = args[i]; - if (PyType_Check(base)) { - if (new_bases) { - /* If we already have made a replacement, then we append every normal base, - otherwise just skip it. */ - if (PyList_Append(new_bases, base) < 0) { - goto error; - } - } - continue; - } - if (_PyObject_LookupAttrId(base, &PyId___mro_entries__, &meth) < 0) { - goto error; - } - if (!meth) { - if (new_bases) { - if (PyList_Append(new_bases, base) < 0) { - goto error; - } - } - continue; - } - new_base = PyObject_CallOneArg(meth, bases); - Py_DECREF(meth); - if (!new_base) { - goto error; - } - if (!PyTuple_Check(new_base)) { - PyErr_SetString(PyExc_TypeError, - "__mro_entries__ must return a tuple"); - Py_DECREF(new_base); - goto error; - } - if (!new_bases) { - /* If this is a first successful replacement, create new_bases list and - copy previously encountered bases. */ - if (!(new_bases = PyList_New(i))) { - Py_DECREF(new_base); - goto error; - } - for (j = 0; j < i; j++) { - base = args[j]; - PyList_SET_ITEM(new_bases, j, base); - Py_INCREF(base); - } - } - j = PyList_GET_SIZE(new_bases); - if (PyList_SetSlice(new_bases, j, j, new_base) < 0) { - Py_DECREF(new_base); - goto error; - } - Py_DECREF(new_base); - } - if (!new_bases) { - return bases; - } - result = PyList_AsTuple(new_bases); - Py_DECREF(new_bases); - return result; - -error: - Py_XDECREF(new_bases); - return NULL; -} - -/* AC: cannot convert yet, waiting for *args support */ -static PyObject * -builtin___build_class__(PyObject *self, PyObject *const *args, Py_ssize_t nargs, - PyObject *kwnames) -{ - PyObject *func, *name, *winner, *prep; - PyObject *cls = NULL, *cell = NULL, *ns = NULL, *meta = NULL, *orig_bases = NULL; - PyObject *mkw = NULL, *bases = NULL; - int isclass = 0; /* initialize to prevent gcc warning */ - - if (nargs < 2) { - PyErr_SetString(PyExc_TypeError, - "__build_class__: not enough arguments"); - return NULL; - } - func = args[0]; /* Better be callable */ - if (!PyFunction_Check(func)) { - PyErr_SetString(PyExc_TypeError, - "__build_class__: func must be a function"); - return NULL; - } - name = args[1]; - if (!PyUnicode_Check(name)) { - PyErr_SetString(PyExc_TypeError, - "__build_class__: name is not a string"); - return NULL; - } - orig_bases = _PyTuple_FromArray(args + 2, nargs - 2); - if (orig_bases == NULL) - return NULL; - - bases = update_bases(orig_bases, args + 2, nargs - 2); - if (bases == NULL) { - Py_DECREF(orig_bases); - return NULL; - } - - if (kwnames == NULL) { - meta = NULL; - mkw = NULL; - } - else { - mkw = _PyStack_AsDict(args + nargs, kwnames); - if (mkw == NULL) { - goto error; - } - - meta = _PyDict_GetItemIdWithError(mkw, &PyId_metaclass); - if (meta != NULL) { - Py_INCREF(meta); - if (_PyDict_DelItemId(mkw, &PyId_metaclass) < 0) { - goto error; - } - /* metaclass is explicitly given, check if it's indeed a class */ - isclass = PyType_Check(meta); - } - else if (PyErr_Occurred()) { - goto error; - } - } - if (meta == NULL) { - /* if there are no bases, use type: */ - if (PyTuple_GET_SIZE(bases) == 0) { - meta = (PyObject *) (&PyType_Type); - } - /* else get the type of the first base */ - else { - PyObject *base0 = PyTuple_GET_ITEM(bases, 0); - meta = (PyObject *)Py_TYPE(base0); - } - Py_INCREF(meta); - isclass = 1; /* meta is really a class */ - } - - if (isclass) { - /* meta is really a class, so check for a more derived - metaclass, or possible metaclass conflicts: */ - winner = (PyObject *)_PyType_CalculateMetaclass((PyTypeObject *)meta, - bases); - if (winner == NULL) { - goto error; - } - if (winner != meta) { - Py_DECREF(meta); - meta = winner; - Py_INCREF(meta); - } - } - /* else: meta is not a class, so we cannot do the metaclass - calculation, so we will use the explicitly given object as it is */ - if (_PyObject_LookupAttrId(meta, &PyId___prepare__, &prep) < 0) { - ns = NULL; - } - else if (prep == NULL) { - ns = PyDict_New(); - } - else { - PyObject *pargs[2] = {name, bases}; - ns = PyObject_VectorcallDict(prep, pargs, 2, mkw); - Py_DECREF(prep); - } - if (ns == NULL) { - goto error; - } - if (!PyMapping_Check(ns)) { - PyErr_Format(PyExc_TypeError, - "%.200s.__prepare__() must return a mapping, not %.200s", - isclass ? ((PyTypeObject *)meta)->tp_name : "<metaclass>", - Py_TYPE(ns)->tp_name); - goto error; - } - PyFrameConstructor *f = PyFunction_AS_FRAME_CONSTRUCTOR(func); - PyThreadState *tstate = PyThreadState_GET(); - cell = _PyEval_Vector(tstate, f, ns, NULL, 0, NULL); - if (cell != NULL) { - if (bases != orig_bases) { - if (PyMapping_SetItemString(ns, "__orig_bases__", orig_bases) < 0) { - goto error; - } - } - PyObject *margs[3] = {name, bases, ns}; - cls = PyObject_VectorcallDict(meta, margs, 3, mkw); - if (cls != NULL && PyType_Check(cls) && PyCell_Check(cell)) { - PyObject *cell_cls = PyCell_GET(cell); - if (cell_cls != cls) { - if (cell_cls == NULL) { - const char *msg = - "__class__ not set defining %.200R as %.200R. " - "Was __classcell__ propagated to type.__new__?"; - PyErr_Format(PyExc_RuntimeError, msg, name, cls); - } else { - const char *msg = - "__class__ set to %.200R defining %.200R as %.200R"; - PyErr_Format(PyExc_TypeError, msg, cell_cls, name, cls); - } - Py_DECREF(cls); - cls = NULL; - goto error; - } - } - } -error: - Py_XDECREF(cell); - Py_XDECREF(ns); - Py_XDECREF(meta); - Py_XDECREF(mkw); - if (bases != orig_bases) { - Py_DECREF(orig_bases); - } - Py_DECREF(bases); - return cls; -} - -PyDoc_STRVAR(build_class_doc, -"__build_class__(func, name, /, *bases, [metaclass], **kwds) -> class\n\ -\n\ -Internal helper function used by the class statement."); - -static PyObject * -builtin___import__(PyObject *self, PyObject *args, PyObject *kwds) -{ - static char *kwlist[] = {"name", "globals", "locals", "fromlist", - "level", 0}; - PyObject *name, *globals = NULL, *locals = NULL, *fromlist = NULL; - int level = 0; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "U|OOOi:__import__", - kwlist, &name, &globals, &locals, &fromlist, &level)) - return NULL; - return PyImport_ImportModuleLevelObject(name, globals, locals, - fromlist, level); -} - -PyDoc_STRVAR(import_doc, -"__import__(name, globals=None, locals=None, fromlist=(), level=0) -> module\n\ -\n\ -Import a module. Because this function is meant for use by the Python\n\ -interpreter and not for general use, it is better to use\n\ -importlib.import_module() to programmatically import a module.\n\ -\n\ -The globals argument is only used to determine the context;\n\ -they are not modified. The locals argument is unused. The fromlist\n\ -should be a list of names to emulate ``from name import ...'', or an\n\ -empty list to emulate ``import name''.\n\ -When importing a module from a package, note that __import__('A.B', ...)\n\ -returns package A when fromlist is empty, but its submodule B when\n\ -fromlist is not empty. The level argument is used to determine whether to\n\ -perform absolute or relative imports: 0 is absolute, while a positive number\n\ -is the number of parent directories to search relative to the current module."); - - -/*[clinic input] -abs as builtin_abs - - x: object - / - -Return the absolute value of the argument. -[clinic start generated code]*/ - -static PyObject * -builtin_abs(PyObject *module, PyObject *x) -/*[clinic end generated code: output=b1b433b9e51356f5 input=bed4ca14e29c20d1]*/ -{ - return PyNumber_Absolute(x); -} - -/*[clinic input] -all as builtin_all - - iterable: object - / - -Return True if bool(x) is True for all values x in the iterable. - -If the iterable is empty, return True. -[clinic start generated code]*/ - -static PyObject * -builtin_all(PyObject *module, PyObject *iterable) -/*[clinic end generated code: output=ca2a7127276f79b3 input=1a7c5d1bc3438a21]*/ -{ - PyObject *it, *item; - PyObject *(*iternext)(PyObject *); - int cmp; - - it = PyObject_GetIter(iterable); - if (it == NULL) - return NULL; - iternext = *Py_TYPE(it)->tp_iternext; - - for (;;) { - item = iternext(it); - if (item == NULL) - break; - cmp = PyObject_IsTrue(item); - Py_DECREF(item); - if (cmp < 0) { - Py_DECREF(it); - return NULL; - } - if (cmp == 0) { - Py_DECREF(it); - Py_RETURN_FALSE; - } - } - Py_DECREF(it); - if (PyErr_Occurred()) { - if (PyErr_ExceptionMatches(PyExc_StopIteration)) - PyErr_Clear(); - else - return NULL; - } - Py_RETURN_TRUE; -} - -/*[clinic input] -any as builtin_any - - iterable: object - / - -Return True if bool(x) is True for any x in the iterable. - -If the iterable is empty, return False. -[clinic start generated code]*/ - -static PyObject * -builtin_any(PyObject *module, PyObject *iterable) -/*[clinic end generated code: output=fa65684748caa60e input=41d7451c23384f24]*/ -{ - PyObject *it, *item; - PyObject *(*iternext)(PyObject *); - int cmp; - - it = PyObject_GetIter(iterable); - if (it == NULL) - return NULL; - iternext = *Py_TYPE(it)->tp_iternext; - - for (;;) { - item = iternext(it); - if (item == NULL) - break; - cmp = PyObject_IsTrue(item); - Py_DECREF(item); - if (cmp < 0) { - Py_DECREF(it); - return NULL; - } - if (cmp > 0) { - Py_DECREF(it); - Py_RETURN_TRUE; - } - } - Py_DECREF(it); - if (PyErr_Occurred()) { - if (PyErr_ExceptionMatches(PyExc_StopIteration)) - PyErr_Clear(); - else - return NULL; - } - Py_RETURN_FALSE; -} - -/*[clinic input] -ascii as builtin_ascii - - obj: object - / - -Return an ASCII-only representation of an object. - -As repr(), return a string containing a printable representation of an -object, but escape the non-ASCII characters in the string returned by -repr() using \\x, \\u or \\U escapes. This generates a string similar -to that returned by repr() in Python 2. -[clinic start generated code]*/ - -static PyObject * -builtin_ascii(PyObject *module, PyObject *obj) -/*[clinic end generated code: output=6d37b3f0984c7eb9 input=4c62732e1b3a3cc9]*/ -{ - return PyObject_ASCII(obj); -} - - -/*[clinic input] -bin as builtin_bin - - number: object - / - -Return the binary representation of an integer. - - >>> bin(2796202) - '0b1010101010101010101010' -[clinic start generated code]*/ - -static PyObject * -builtin_bin(PyObject *module, PyObject *number) -/*[clinic end generated code: output=b6fc4ad5e649f4f7 input=53f8a0264bacaf90]*/ -{ - return PyNumber_ToBase(number, 2); -} - - -/*[clinic input] -callable as builtin_callable - - obj: object - / - -Return whether the object is callable (i.e., some kind of function). - -Note that classes are callable, as are instances of classes with a -__call__() method. -[clinic start generated code]*/ - -static PyObject * -builtin_callable(PyObject *module, PyObject *obj) -/*[clinic end generated code: output=2b095d59d934cb7e input=1423bab99cc41f58]*/ -{ - return PyBool_FromLong((long)PyCallable_Check(obj)); -} - -static PyObject * -builtin_breakpoint(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *keywords) -{ - PyObject *hook = PySys_GetObject("breakpointhook"); - - if (hook == NULL) { - PyErr_SetString(PyExc_RuntimeError, "lost sys.breakpointhook"); - return NULL; - } - - if (PySys_Audit("builtins.breakpoint", "O", hook) < 0) { - return NULL; - } - - Py_INCREF(hook); - PyObject *retval = PyObject_Vectorcall(hook, args, nargs, keywords); - Py_DECREF(hook); - return retval; -} - -PyDoc_STRVAR(breakpoint_doc, -"breakpoint(*args, **kws)\n\ -\n\ -Call sys.breakpointhook(*args, **kws). sys.breakpointhook() must accept\n\ -whatever arguments are passed.\n\ -\n\ -By default, this drops you into the pdb debugger."); - -typedef struct { - PyObject_HEAD - PyObject *func; - PyObject *it; -} filterobject; - -static PyObject * -filter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - PyObject *func, *seq; - PyObject *it; - filterobject *lz; - - if (type == &PyFilter_Type && !_PyArg_NoKeywords("filter", kwds)) - return NULL; - - if (!PyArg_UnpackTuple(args, "filter", 2, 2, &func, &seq)) - return NULL; - - /* Get iterator. */ - it = PyObject_GetIter(seq); - if (it == NULL) - return NULL; - - /* create filterobject structure */ - lz = (filterobject *)type->tp_alloc(type, 0); - if (lz == NULL) { - Py_DECREF(it); - return NULL; - } - - lz->func = Py_NewRef(func); - lz->it = it; - - return (PyObject *)lz; -} - -static PyObject * -filter_vectorcall(PyObject *type, PyObject * const*args, - size_t nargsf, PyObject *kwnames) -{ - PyTypeObject *tp = (PyTypeObject *)type; - if (tp == &PyFilter_Type && !_PyArg_NoKwnames("filter", kwnames)) { - return NULL; - } - - Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); - if (!_PyArg_CheckPositional("filter", nargs, 2, 2)) { - return NULL; - } - - PyObject *it = PyObject_GetIter(args[1]); - if (it == NULL) { - return NULL; - } - - filterobject *lz = (filterobject *)tp->tp_alloc(tp, 0); - - if (lz == NULL) { - Py_DECREF(it); - return NULL; - } - - lz->func = Py_NewRef(args[0]); - lz->it = it; - - return (PyObject *)lz; -} - -static void -filter_dealloc(filterobject *lz) -{ - PyObject_GC_UnTrack(lz); - Py_XDECREF(lz->func); - Py_XDECREF(lz->it); - Py_TYPE(lz)->tp_free(lz); -} - -static int -filter_traverse(filterobject *lz, visitproc visit, void *arg) -{ - Py_VISIT(lz->it); - Py_VISIT(lz->func); - return 0; -} - -static PyObject * -filter_next(filterobject *lz) -{ - PyObject *item; - PyObject *it = lz->it; - long ok; - PyObject *(*iternext)(PyObject *); - int checktrue = lz->func == Py_None || lz->func == (PyObject *)&PyBool_Type; - - iternext = *Py_TYPE(it)->tp_iternext; - for (;;) { - item = iternext(it); - if (item == NULL) - return NULL; - - if (checktrue) { - ok = PyObject_IsTrue(item); - } else { - PyObject *good; - good = PyObject_CallOneArg(lz->func, item); - if (good == NULL) { - Py_DECREF(item); - return NULL; - } - ok = PyObject_IsTrue(good); - Py_DECREF(good); - } - if (ok > 0) - return item; - Py_DECREF(item); - if (ok < 0) - return NULL; - } -} - -static PyObject * -filter_reduce(filterobject *lz, PyObject *Py_UNUSED(ignored)) -{ - return Py_BuildValue("O(OO)", Py_TYPE(lz), lz->func, lz->it); -} - -PyDoc_STRVAR(reduce_doc, "Return state information for pickling."); - -static PyMethodDef filter_methods[] = { - {"__reduce__", (PyCFunction)filter_reduce, METH_NOARGS, reduce_doc}, - {NULL, NULL} /* sentinel */ -}; - -PyDoc_STRVAR(filter_doc, -"filter(function or None, iterable) --> filter object\n\ -\n\ -Return an iterator yielding those items of iterable for which function(item)\n\ -is true. If function is None, return the items that are true."); - -PyTypeObject PyFilter_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "filter", /* tp_name */ - sizeof(filterobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)filter_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ - filter_doc, /* tp_doc */ - (traverseproc)filter_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)filter_next, /* tp_iternext */ - filter_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - PyType_GenericAlloc, /* tp_alloc */ - filter_new, /* tp_new */ - PyObject_GC_Del, /* tp_free */ - .tp_vectorcall = (vectorcallfunc)filter_vectorcall -}; - - -/*[clinic input] -format as builtin_format - - value: object - format_spec: unicode(c_default="NULL") = '' - / - -Return value.__format__(format_spec) - -format_spec defaults to the empty string. -See the Format Specification Mini-Language section of help('FORMATTING') for -details. -[clinic start generated code]*/ - -static PyObject * -builtin_format_impl(PyObject *module, PyObject *value, PyObject *format_spec) -/*[clinic end generated code: output=2f40bdfa4954b077 input=88339c93ea522b33]*/ -{ - return PyObject_Format(value, format_spec); -} - -/*[clinic input] -chr as builtin_chr - - i: int - / - -Return a Unicode string of one character with ordinal i; 0 <= i <= 0x10ffff. -[clinic start generated code]*/ - -static PyObject * -builtin_chr_impl(PyObject *module, int i) -/*[clinic end generated code: output=c733afcd200afcb7 input=3f604ef45a70750d]*/ -{ - return PyUnicode_FromOrdinal(i); -} - - -/*[clinic input] -compile as builtin_compile - - source: object - filename: object(converter="PyUnicode_FSDecoder") - mode: str - flags: int = 0 - dont_inherit: bool(accept={int}) = False - optimize: int = -1 - * - _feature_version as feature_version: int = -1 - -Compile source into a code object that can be executed by exec() or eval(). - -The source code may represent a Python module, statement or expression. -The filename will be used for run-time error messages. -The mode must be 'exec' to compile a module, 'single' to compile a -single (interactive) statement, or 'eval' to compile an expression. -The flags argument, if present, controls which future statements influence -the compilation of the code. -The dont_inherit argument, if true, stops the compilation inheriting -the effects of any future statements in effect in the code calling -compile; if absent or false these statements do influence the compilation, -in addition to any features explicitly specified. -[clinic start generated code]*/ - -static PyObject * -builtin_compile_impl(PyObject *module, PyObject *source, PyObject *filename, - const char *mode, int flags, int dont_inherit, - int optimize, int feature_version) -/*[clinic end generated code: output=b0c09c84f116d3d7 input=40171fb92c1d580d]*/ -{ - PyObject *source_copy; - const char *str; - int compile_mode = -1; - int is_ast; - int start[] = {Py_file_input, Py_eval_input, Py_single_input, Py_func_type_input}; - PyObject *result; - - PyCompilerFlags cf = _PyCompilerFlags_INIT; - cf.cf_flags = flags | PyCF_SOURCE_IS_UTF8; - if (feature_version >= 0 && (flags & PyCF_ONLY_AST)) { - cf.cf_feature_version = feature_version; - } - - if (flags & - ~(PyCF_MASK | PyCF_MASK_OBSOLETE | PyCF_COMPILE_MASK)) - { - PyErr_SetString(PyExc_ValueError, - "compile(): unrecognised flags"); - goto error; - } - /* XXX Warn if (supplied_flags & PyCF_MASK_OBSOLETE) != 0? */ - - if (optimize < -1 || optimize > 2) { - PyErr_SetString(PyExc_ValueError, - "compile(): invalid optimize value"); - goto error; - } - - if (!dont_inherit) { - PyEval_MergeCompilerFlags(&cf); - } - - if (strcmp(mode, "exec") == 0) - compile_mode = 0; - else if (strcmp(mode, "eval") == 0) - compile_mode = 1; - else if (strcmp(mode, "single") == 0) - compile_mode = 2; - else if (strcmp(mode, "func_type") == 0) { - if (!(flags & PyCF_ONLY_AST)) { - PyErr_SetString(PyExc_ValueError, - "compile() mode 'func_type' requires flag PyCF_ONLY_AST"); - goto error; - } - compile_mode = 3; - } - else { - const char *msg; - if (flags & PyCF_ONLY_AST) - msg = "compile() mode must be 'exec', 'eval', 'single' or 'func_type'"; - else - msg = "compile() mode must be 'exec', 'eval' or 'single'"; - PyErr_SetString(PyExc_ValueError, msg); - goto error; - } - - is_ast = PyAST_Check(source); - if (is_ast == -1) - goto error; - if (is_ast) { - if (flags & PyCF_ONLY_AST) { - Py_INCREF(source); - result = source; - } - else { - PyArena *arena; - mod_ty mod; - - arena = _PyArena_New(); - if (arena == NULL) - goto error; - mod = PyAST_obj2mod(source, arena, compile_mode); - if (mod == NULL || !_PyAST_Validate(mod)) { - _PyArena_Free(arena); - goto error; - } - result = (PyObject*)_PyAST_Compile(mod, filename, - &cf, optimize, arena); - _PyArena_Free(arena); - } - goto finally; - } - - str = _Py_SourceAsString(source, "compile", "string, bytes or AST", &cf, &source_copy); - if (str == NULL) - goto error; - - result = Py_CompileStringObject(str, filename, start[compile_mode], &cf, optimize); - - Py_XDECREF(source_copy); - goto finally; - -error: - result = NULL; -finally: - Py_DECREF(filename); - return result; -} - -/* AC: cannot convert yet, as needs PEP 457 group support in inspect */ -static PyObject * -builtin_dir(PyObject *self, PyObject *args) -{ - PyObject *arg = NULL; - - if (!PyArg_UnpackTuple(args, "dir", 0, 1, &arg)) - return NULL; - return PyObject_Dir(arg); -} - -PyDoc_STRVAR(dir_doc, -"dir([object]) -> list of strings\n" -"\n" -"If called without an argument, return the names in the current scope.\n" -"Else, return an alphabetized list of names comprising (some of) the attributes\n" -"of the given object, and of attributes reachable from it.\n" -"If the object supplies a method named __dir__, it will be used; otherwise\n" -"the default dir() logic is used and returns:\n" -" for a module object: the module's attributes.\n" -" for a class object: its attributes, and recursively the attributes\n" -" of its bases.\n" -" for any other object: its attributes, its class's attributes, and\n" -" recursively the attributes of its class's base classes."); - -/*[clinic input] -divmod as builtin_divmod - - x: object - y: object - / - -Return the tuple (x//y, x%y). Invariant: div*y + mod == x. -[clinic start generated code]*/ - -static PyObject * -builtin_divmod_impl(PyObject *module, PyObject *x, PyObject *y) -/*[clinic end generated code: output=b06d8a5f6e0c745e input=175ad9c84ff41a85]*/ -{ - return PyNumber_Divmod(x, y); -} - - -/*[clinic input] -eval as builtin_eval - - source: object - globals: object = None - locals: object = None - / - -Evaluate the given source in the context of globals and locals. - -The source may be a string representing a Python expression -or a code object as returned by compile(). -The globals must be a dictionary and locals can be any mapping, -defaulting to the current globals and locals. -If only globals is given, locals defaults to it. -[clinic start generated code]*/ - -static PyObject * -builtin_eval_impl(PyObject *module, PyObject *source, PyObject *globals, - PyObject *locals) -/*[clinic end generated code: output=0a0824aa70093116 input=11ee718a8640e527]*/ -{ - PyObject *result, *source_copy; - const char *str; - - if (locals != Py_None && !PyMapping_Check(locals)) { - PyErr_SetString(PyExc_TypeError, "locals must be a mapping"); - return NULL; - } - if (globals != Py_None && !PyDict_Check(globals)) { - PyErr_SetString(PyExc_TypeError, PyMapping_Check(globals) ? - "globals must be a real dict; try eval(expr, {}, mapping)" - : "globals must be a dict"); - return NULL; - } - if (globals == Py_None) { - globals = PyEval_GetGlobals(); - if (locals == Py_None) { - locals = PyEval_GetLocals(); - if (locals == NULL) - return NULL; - } - } - else if (locals == Py_None) - locals = globals; - - if (globals == NULL || locals == NULL) { - PyErr_SetString(PyExc_TypeError, - "eval must be given globals and locals " - "when called without a frame"); - return NULL; - } - - int r = _PyDict_ContainsId(globals, &PyId___builtins__); - if (r == 0) { - r = _PyDict_SetItemId(globals, &PyId___builtins__, - PyEval_GetBuiltins()); - } - if (r < 0) { - return NULL; - } - - if (PyCode_Check(source)) { - if (PySys_Audit("exec", "O", source) < 0) { - return NULL; - } - - if (PyCode_GetNumFree((PyCodeObject *)source) > 0) { - PyErr_SetString(PyExc_TypeError, - "code object passed to eval() may not contain free variables"); - return NULL; - } - return PyEval_EvalCode(source, globals, locals); - } - - PyCompilerFlags cf = _PyCompilerFlags_INIT; - cf.cf_flags = PyCF_SOURCE_IS_UTF8; - str = _Py_SourceAsString(source, "eval", "string, bytes or code", &cf, &source_copy); - if (str == NULL) - return NULL; - - while (*str == ' ' || *str == '\t') - str++; - - (void)PyEval_MergeCompilerFlags(&cf); - result = PyRun_StringFlags(str, Py_eval_input, globals, locals, &cf); - Py_XDECREF(source_copy); - return result; -} - -/*[clinic input] -exec as builtin_exec - - source: object - globals: object = None - locals: object = None - / - -Execute the given source in the context of globals and locals. - -The source may be a string representing one or more Python statements -or a code object as returned by compile(). -The globals must be a dictionary and locals can be any mapping, -defaulting to the current globals and locals. -If only globals is given, locals defaults to it. -[clinic start generated code]*/ - -static PyObject * -builtin_exec_impl(PyObject *module, PyObject *source, PyObject *globals, - PyObject *locals) -/*[clinic end generated code: output=3c90efc6ab68ef5d input=01ca3e1c01692829]*/ -{ - PyObject *v; - - if (globals == Py_None) { - globals = PyEval_GetGlobals(); - if (locals == Py_None) { - locals = PyEval_GetLocals(); - if (locals == NULL) - return NULL; - } - if (!globals || !locals) { - PyErr_SetString(PyExc_SystemError, - "globals and locals cannot be NULL"); - return NULL; - } - } - else if (locals == Py_None) - locals = globals; - - if (!PyDict_Check(globals)) { - PyErr_Format(PyExc_TypeError, "exec() globals must be a dict, not %.100s", - Py_TYPE(globals)->tp_name); - return NULL; - } - if (!PyMapping_Check(locals)) { - PyErr_Format(PyExc_TypeError, - "locals must be a mapping or None, not %.100s", - Py_TYPE(locals)->tp_name); - return NULL; - } - int r = _PyDict_ContainsId(globals, &PyId___builtins__); - if (r == 0) { - r = _PyDict_SetItemId(globals, &PyId___builtins__, - PyEval_GetBuiltins()); - } - if (r < 0) { - return NULL; - } - - if (PyCode_Check(source)) { - if (PySys_Audit("exec", "O", source) < 0) { - return NULL; - } - - if (PyCode_GetNumFree((PyCodeObject *)source) > 0) { - PyErr_SetString(PyExc_TypeError, - "code object passed to exec() may not " - "contain free variables"); - return NULL; - } - v = PyEval_EvalCode(source, globals, locals); - } - else { - PyObject *source_copy; - const char *str; - PyCompilerFlags cf = _PyCompilerFlags_INIT; - cf.cf_flags = PyCF_SOURCE_IS_UTF8; - str = _Py_SourceAsString(source, "exec", - "string, bytes or code", &cf, - &source_copy); - if (str == NULL) - return NULL; - if (PyEval_MergeCompilerFlags(&cf)) - v = PyRun_StringFlags(str, Py_file_input, globals, - locals, &cf); - else - v = PyRun_String(str, Py_file_input, globals, locals); - Py_XDECREF(source_copy); - } - if (v == NULL) - return NULL; - Py_DECREF(v); - Py_RETURN_NONE; -} - - -/* AC: cannot convert yet, as needs PEP 457 group support in inspect */ -static PyObject * -builtin_getattr(PyObject *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *v, *name, *result; - - if (!_PyArg_CheckPositional("getattr", nargs, 2, 3)) - return NULL; - - v = args[0]; - name = args[1]; - if (!PyUnicode_Check(name)) { - PyErr_SetString(PyExc_TypeError, - "getattr(): attribute name must be string"); - return NULL; - } - if (nargs > 2) { - if (_PyObject_LookupAttr(v, name, &result) == 0) { - PyObject *dflt = args[2]; - Py_INCREF(dflt); - return dflt; - } - } - else { - result = PyObject_GetAttr(v, name); - } - return result; -} - -PyDoc_STRVAR(getattr_doc, -"getattr(object, name[, default]) -> value\n\ -\n\ -Get a named attribute from an object; getattr(x, 'y') is equivalent to x.y.\n\ -When a default argument is given, it is returned when the attribute doesn't\n\ -exist; without it, an exception is raised in that case."); - - -/*[clinic input] -globals as builtin_globals - -Return the dictionary containing the current scope's global variables. - -NOTE: Updates to this dictionary *will* affect name lookups in the current -global scope and vice-versa. -[clinic start generated code]*/ - -static PyObject * -builtin_globals_impl(PyObject *module) -/*[clinic end generated code: output=e5dd1527067b94d2 input=9327576f92bb48ba]*/ -{ - PyObject *d; - - d = PyEval_GetGlobals(); - Py_XINCREF(d); - return d; -} - - -/*[clinic input] -hasattr as builtin_hasattr - - obj: object - name: object - / - -Return whether the object has an attribute with the given name. - -This is done by calling getattr(obj, name) and catching AttributeError. -[clinic start generated code]*/ - -static PyObject * -builtin_hasattr_impl(PyObject *module, PyObject *obj, PyObject *name) -/*[clinic end generated code: output=a7aff2090a4151e5 input=0faec9787d979542]*/ -{ - PyObject *v; - - if (!PyUnicode_Check(name)) { - PyErr_SetString(PyExc_TypeError, - "hasattr(): attribute name must be string"); - return NULL; - } - if (_PyObject_LookupAttr(obj, name, &v) < 0) { - return NULL; - } - if (v == NULL) { - Py_RETURN_FALSE; - } - Py_DECREF(v); - Py_RETURN_TRUE; -} - - -/* AC: gdb's integration with CPython relies on builtin_id having - * the *exact* parameter names of "self" and "v", so we ensure we - * preserve those name rather than using the AC defaults. - */ -/*[clinic input] -id as builtin_id - - self: self(type="PyModuleDef *") - obj as v: object - / - -Return the identity of an object. - -This is guaranteed to be unique among simultaneously existing objects. -(CPython uses the object's memory address.) -[clinic start generated code]*/ - -static PyObject * -builtin_id(PyModuleDef *self, PyObject *v) -/*[clinic end generated code: output=0aa640785f697f65 input=5a534136419631f4]*/ -{ - PyObject *id = PyLong_FromVoidPtr(v); - - if (id && PySys_Audit("builtins.id", "O", id) < 0) { - Py_DECREF(id); - return NULL; - } - - return id; -} - - -/* map object ************************************************************/ - -typedef struct { - PyObject_HEAD - PyObject *iters; - PyObject *func; -} mapobject; - -static PyObject * -map_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - PyObject *it, *iters, *func; - mapobject *lz; - Py_ssize_t numargs, i; - - if (type == &PyMap_Type && !_PyArg_NoKeywords("map", kwds)) - return NULL; - - numargs = PyTuple_Size(args); - if (numargs < 2) { - PyErr_SetString(PyExc_TypeError, - "map() must have at least two arguments."); - return NULL; - } - - iters = PyTuple_New(numargs-1); - if (iters == NULL) - return NULL; - - for (i=1 ; i<numargs ; i++) { - /* Get iterator. */ - it = PyObject_GetIter(PyTuple_GET_ITEM(args, i)); - if (it == NULL) { - Py_DECREF(iters); - return NULL; - } - PyTuple_SET_ITEM(iters, i-1, it); - } - - /* create mapobject structure */ - lz = (mapobject *)type->tp_alloc(type, 0); - if (lz == NULL) { - Py_DECREF(iters); - return NULL; - } - lz->iters = iters; - func = PyTuple_GET_ITEM(args, 0); - lz->func = Py_NewRef(func); - - return (PyObject *)lz; -} - -static PyObject * -map_vectorcall(PyObject *type, PyObject * const*args, - size_t nargsf, PyObject *kwnames) -{ - PyTypeObject *tp = (PyTypeObject *)type; - if (tp == &PyMap_Type && !_PyArg_NoKwnames("map", kwnames)) { - return NULL; - } - - Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); - if (nargs < 2) { - PyErr_SetString(PyExc_TypeError, - "map() must have at least two arguments."); - return NULL; - } - - PyObject *iters = PyTuple_New(nargs-1); - if (iters == NULL) { - return NULL; - } - - for (int i=1; i<nargs; i++) { - PyObject *it = PyObject_GetIter(args[i]); - if (it == NULL) { - Py_DECREF(iters); - return NULL; - } - PyTuple_SET_ITEM(iters, i-1, it); - } - - mapobject *lz = (mapobject *)tp->tp_alloc(tp, 0); - if (lz == NULL) { - Py_DECREF(iters); - return NULL; - } - lz->iters = iters; - lz->func = Py_NewRef(args[0]); - - return (PyObject *)lz; -} - -static void -map_dealloc(mapobject *lz) -{ - PyObject_GC_UnTrack(lz); - Py_XDECREF(lz->iters); - Py_XDECREF(lz->func); - Py_TYPE(lz)->tp_free(lz); -} - -static int -map_traverse(mapobject *lz, visitproc visit, void *arg) -{ - Py_VISIT(lz->iters); - Py_VISIT(lz->func); - return 0; -} - -static PyObject * -map_next(mapobject *lz) -{ - PyObject *small_stack[_PY_FASTCALL_SMALL_STACK]; - PyObject **stack; - PyObject *result = NULL; - PyThreadState *tstate = _PyThreadState_GET(); - - const Py_ssize_t niters = PyTuple_GET_SIZE(lz->iters); - if (niters <= (Py_ssize_t)Py_ARRAY_LENGTH(small_stack)) { - stack = small_stack; - } - else { - stack = PyMem_Malloc(niters * sizeof(stack[0])); - if (stack == NULL) { - _PyErr_NoMemory(tstate); - return NULL; - } - } - - Py_ssize_t nargs = 0; - for (Py_ssize_t i=0; i < niters; i++) { - PyObject *it = PyTuple_GET_ITEM(lz->iters, i); - PyObject *val = Py_TYPE(it)->tp_iternext(it); - if (val == NULL) { - goto exit; - } - stack[i] = val; - nargs++; - } - - result = _PyObject_VectorcallTstate(tstate, lz->func, stack, nargs, NULL); - -exit: - for (Py_ssize_t i=0; i < nargs; i++) { - Py_DECREF(stack[i]); - } - if (stack != small_stack) { - PyMem_Free(stack); - } - return result; -} - -static PyObject * -map_reduce(mapobject *lz, PyObject *Py_UNUSED(ignored)) -{ - Py_ssize_t numargs = PyTuple_GET_SIZE(lz->iters); - PyObject *args = PyTuple_New(numargs+1); - Py_ssize_t i; - if (args == NULL) - return NULL; - Py_INCREF(lz->func); - PyTuple_SET_ITEM(args, 0, lz->func); - for (i = 0; i<numargs; i++){ - PyObject *it = PyTuple_GET_ITEM(lz->iters, i); - Py_INCREF(it); - PyTuple_SET_ITEM(args, i+1, it); - } - - return Py_BuildValue("ON", Py_TYPE(lz), args); -} - -static PyMethodDef map_methods[] = { - {"__reduce__", (PyCFunction)map_reduce, METH_NOARGS, reduce_doc}, - {NULL, NULL} /* sentinel */ -}; - - -PyDoc_STRVAR(map_doc, -"map(func, *iterables) --> map object\n\ -\n\ -Make an iterator that computes the function using arguments from\n\ -each of the iterables. Stops when the shortest iterable is exhausted."); - -PyTypeObject PyMap_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "map", /* tp_name */ - sizeof(mapobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)map_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ - map_doc, /* tp_doc */ - (traverseproc)map_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)map_next, /* tp_iternext */ - map_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - PyType_GenericAlloc, /* tp_alloc */ - map_new, /* tp_new */ - PyObject_GC_Del, /* tp_free */ - .tp_vectorcall = (vectorcallfunc)map_vectorcall -}; - - -/* AC: cannot convert yet, as needs PEP 457 group support in inspect */ -static PyObject * -builtin_next(PyObject *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *it, *res; - - if (!_PyArg_CheckPositional("next", nargs, 1, 2)) - return NULL; - - it = args[0]; - if (!PyIter_Check(it)) { - PyErr_Format(PyExc_TypeError, - "'%.200s' object is not an iterator", - Py_TYPE(it)->tp_name); - return NULL; - } - - res = (*Py_TYPE(it)->tp_iternext)(it); - if (res != NULL) { - return res; - } else if (nargs > 1) { - PyObject *def = args[1]; - if (PyErr_Occurred()) { - if(!PyErr_ExceptionMatches(PyExc_StopIteration)) - return NULL; - PyErr_Clear(); - } - Py_INCREF(def); - return def; - } else if (PyErr_Occurred()) { - return NULL; - } else { - PyErr_SetNone(PyExc_StopIteration); - return NULL; - } -} - -PyDoc_STRVAR(next_doc, -"next(iterator[, default])\n\ -\n\ -Return the next item from the iterator. If default is given and the iterator\n\ -is exhausted, it is returned instead of raising StopIteration."); - - -/*[clinic input] -setattr as builtin_setattr - - obj: object - name: object - value: object - / - -Sets the named attribute on the given object to the specified value. - -setattr(x, 'y', v) is equivalent to ``x.y = v'' -[clinic start generated code]*/ - -static PyObject * -builtin_setattr_impl(PyObject *module, PyObject *obj, PyObject *name, - PyObject *value) -/*[clinic end generated code: output=dc2ce1d1add9acb4 input=bd2b7ca6875a1899]*/ -{ - if (PyObject_SetAttr(obj, name, value) != 0) - return NULL; - Py_RETURN_NONE; -} - - -/*[clinic input] -delattr as builtin_delattr - - obj: object - name: object - / - -Deletes the named attribute from the given object. - -delattr(x, 'y') is equivalent to ``del x.y'' -[clinic start generated code]*/ - -static PyObject * -builtin_delattr_impl(PyObject *module, PyObject *obj, PyObject *name) -/*[clinic end generated code: output=85134bc58dff79fa input=db16685d6b4b9410]*/ -{ - if (PyObject_SetAttr(obj, name, (PyObject *)NULL) != 0) - return NULL; - Py_RETURN_NONE; -} - - -/*[clinic input] -hash as builtin_hash - - obj: object - / - -Return the hash value for the given object. - -Two objects that compare equal must also have the same hash value, but the -reverse is not necessarily true. -[clinic start generated code]*/ - -static PyObject * -builtin_hash(PyObject *module, PyObject *obj) -/*[clinic end generated code: output=237668e9d7688db7 input=58c48be822bf9c54]*/ -{ - Py_hash_t x; - - x = PyObject_Hash(obj); - if (x == -1) - return NULL; - return PyLong_FromSsize_t(x); -} - - -/*[clinic input] -hex as builtin_hex - - number: object - / - -Return the hexadecimal representation of an integer. - - >>> hex(12648430) - '0xc0ffee' -[clinic start generated code]*/ - -static PyObject * -builtin_hex(PyObject *module, PyObject *number) -/*[clinic end generated code: output=e46b612169099408 input=e645aff5fc7d540e]*/ -{ - return PyNumber_ToBase(number, 16); -} - - -/* AC: cannot convert yet, as needs PEP 457 group support in inspect */ -static PyObject * -builtin_iter(PyObject *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *v; - - if (!_PyArg_CheckPositional("iter", nargs, 1, 2)) - return NULL; - v = args[0]; - if (nargs == 1) - return PyObject_GetIter(v); - if (!PyCallable_Check(v)) { - PyErr_SetString(PyExc_TypeError, - "iter(v, w): v must be callable"); - return NULL; - } - PyObject *sentinel = args[1]; - return PyCallIter_New(v, sentinel); -} - -PyDoc_STRVAR(iter_doc, -"iter(iterable) -> iterator\n\ -iter(callable, sentinel) -> iterator\n\ -\n\ -Get an iterator from an object. In the first form, the argument must\n\ -supply its own iterator, or be a sequence.\n\ -In the second form, the callable is called until it returns the sentinel."); - - -/*[clinic input] -aiter as builtin_aiter - - async_iterable: object - / - -Return an AsyncIterator for an AsyncIterable object. -[clinic start generated code]*/ - -static PyObject * -builtin_aiter(PyObject *module, PyObject *async_iterable) -/*[clinic end generated code: output=1bae108d86f7960e input=473993d0cacc7d23]*/ -{ - return PyObject_GetAIter(async_iterable); -} - -PyObject *PyAnextAwaitable_New(PyObject *, PyObject *); - -/*[clinic input] -anext as builtin_anext - - aiterator: object - default: object = NULL - / - -Return the next item from the async iterator. -[clinic start generated code]*/ - -static PyObject * -builtin_anext_impl(PyObject *module, PyObject *aiterator, - PyObject *default_value) -/*[clinic end generated code: output=f02c060c163a81fa input=699d11f4e38eca24]*/ -{ - PyTypeObject *t; - PyObject *awaitable; - - t = Py_TYPE(aiterator); - if (t->tp_as_async == NULL || t->tp_as_async->am_anext == NULL) { - PyErr_Format(PyExc_TypeError, - "'%.200s' object is not an async iterator", - t->tp_name); - return NULL; - } - - awaitable = (*t->tp_as_async->am_anext)(aiterator); - if (default_value == NULL) { - return awaitable; - } - - PyObject* new_awaitable = PyAnextAwaitable_New( - awaitable, default_value); - Py_DECREF(awaitable); - return new_awaitable; -} - - -/*[clinic input] -len as builtin_len - - obj: object - / - -Return the number of items in a container. -[clinic start generated code]*/ - -static PyObject * -builtin_len(PyObject *module, PyObject *obj) -/*[clinic end generated code: output=fa7a270d314dfb6c input=bc55598da9e9c9b5]*/ -{ - Py_ssize_t res; - - res = PyObject_Size(obj); - if (res < 0) { - assert(PyErr_Occurred()); - return NULL; - } - return PyLong_FromSsize_t(res); -} - - -/*[clinic input] -locals as builtin_locals - -Return a dictionary containing the current scope's local variables. - -NOTE: Whether or not updates to this dictionary will affect name lookups in -the local scope and vice-versa is *implementation dependent* and not -covered by any backwards compatibility guarantees. -[clinic start generated code]*/ - -static PyObject * -builtin_locals_impl(PyObject *module) -/*[clinic end generated code: output=b46c94015ce11448 input=7874018d478d5c4b]*/ -{ - PyObject *d; - - d = PyEval_GetLocals(); - Py_XINCREF(d); - return d; -} - - -static PyObject * -min_max(PyObject *args, PyObject *kwds, int op) -{ - PyObject *v, *it, *item, *val, *maxitem, *maxval, *keyfunc=NULL; - PyObject *emptytuple, *defaultval = NULL; - static char *kwlist[] = {"key", "default", NULL}; - const char *name = op == Py_LT ? "min" : "max"; - const int positional = PyTuple_Size(args) > 1; - int ret; - - if (positional) { - v = args; - } - else if (!PyArg_UnpackTuple(args, name, 1, 1, &v)) { - if (PyExceptionClass_Check(PyExc_TypeError)) { - PyErr_Format(PyExc_TypeError, "%s expected at least 1 argument, got 0", name); - } - return NULL; - } - - emptytuple = PyTuple_New(0); - if (emptytuple == NULL) - return NULL; - ret = PyArg_ParseTupleAndKeywords(emptytuple, kwds, - (op == Py_LT) ? "|$OO:min" : "|$OO:max", - kwlist, &keyfunc, &defaultval); - Py_DECREF(emptytuple); - if (!ret) - return NULL; - - if (positional && defaultval != NULL) { - PyErr_Format(PyExc_TypeError, - "Cannot specify a default for %s() with multiple " - "positional arguments", name); - return NULL; - } - - it = PyObject_GetIter(v); - if (it == NULL) { - return NULL; - } - - if (keyfunc == Py_None) { - keyfunc = NULL; - } - - maxitem = NULL; /* the result */ - maxval = NULL; /* the value associated with the result */ - while (( item = PyIter_Next(it) )) { - /* get the value from the key function */ - if (keyfunc != NULL) { - val = PyObject_CallOneArg(keyfunc, item); - if (val == NULL) - goto Fail_it_item; - } - /* no key function; the value is the item */ - else { - val = item; - Py_INCREF(val); - } - - /* maximum value and item are unset; set them */ - if (maxval == NULL) { - maxitem = item; - maxval = val; - } - /* maximum value and item are set; update them as necessary */ - else { - int cmp = PyObject_RichCompareBool(val, maxval, op); - if (cmp < 0) - goto Fail_it_item_and_val; - else if (cmp > 0) { - Py_DECREF(maxval); - Py_DECREF(maxitem); - maxval = val; - maxitem = item; - } - else { - Py_DECREF(item); - Py_DECREF(val); - } - } - } - if (PyErr_Occurred()) - goto Fail_it; - if (maxval == NULL) { - assert(maxitem == NULL); - if (defaultval != NULL) { - Py_INCREF(defaultval); - maxitem = defaultval; - } else { - PyErr_Format(PyExc_ValueError, - "%s() arg is an empty sequence", name); - } - } - else - Py_DECREF(maxval); - Py_DECREF(it); - return maxitem; - -Fail_it_item_and_val: - Py_DECREF(val); -Fail_it_item: - Py_DECREF(item); -Fail_it: - Py_XDECREF(maxval); - Py_XDECREF(maxitem); - Py_DECREF(it); - return NULL; -} - -/* AC: cannot convert yet, waiting for *args support */ -static PyObject * -builtin_min(PyObject *self, PyObject *args, PyObject *kwds) -{ - return min_max(args, kwds, Py_LT); -} - -PyDoc_STRVAR(min_doc, -"min(iterable, *[, default=obj, key=func]) -> value\n\ -min(arg1, arg2, *args, *[, key=func]) -> value\n\ -\n\ -With a single iterable argument, return its smallest item. The\n\ -default keyword-only argument specifies an object to return if\n\ -the provided iterable is empty.\n\ -With two or more arguments, return the smallest argument."); - - -/* AC: cannot convert yet, waiting for *args support */ -static PyObject * -builtin_max(PyObject *self, PyObject *args, PyObject *kwds) -{ - return min_max(args, kwds, Py_GT); -} - -PyDoc_STRVAR(max_doc, -"max(iterable, *[, default=obj, key=func]) -> value\n\ -max(arg1, arg2, *args, *[, key=func]) -> value\n\ -\n\ -With a single iterable argument, return its biggest item. The\n\ -default keyword-only argument specifies an object to return if\n\ -the provided iterable is empty.\n\ -With two or more arguments, return the largest argument."); - - -/*[clinic input] -oct as builtin_oct - - number: object - / - -Return the octal representation of an integer. - - >>> oct(342391) - '0o1234567' -[clinic start generated code]*/ - -static PyObject * -builtin_oct(PyObject *module, PyObject *number) -/*[clinic end generated code: output=40a34656b6875352 input=ad6b274af4016c72]*/ -{ - return PyNumber_ToBase(number, 8); -} - - -/*[clinic input] -ord as builtin_ord - - c: object - / - -Return the Unicode code point for a one-character string. -[clinic start generated code]*/ - -static PyObject * -builtin_ord(PyObject *module, PyObject *c) -/*[clinic end generated code: output=4fa5e87a323bae71 input=3064e5d6203ad012]*/ -{ - long ord; - Py_ssize_t size; - - if (PyBytes_Check(c)) { - size = PyBytes_GET_SIZE(c); - if (size == 1) { - ord = (long)((unsigned char)*PyBytes_AS_STRING(c)); - return PyLong_FromLong(ord); - } - } - else if (PyUnicode_Check(c)) { - if (PyUnicode_READY(c) == -1) - return NULL; - size = PyUnicode_GET_LENGTH(c); - if (size == 1) { - ord = (long)PyUnicode_READ_CHAR(c, 0); - return PyLong_FromLong(ord); - } - } - else if (PyByteArray_Check(c)) { - /* XXX Hopefully this is temporary */ - size = PyByteArray_GET_SIZE(c); - if (size == 1) { - ord = (long)((unsigned char)*PyByteArray_AS_STRING(c)); - return PyLong_FromLong(ord); - } - } - else { - PyErr_Format(PyExc_TypeError, - "ord() expected string of length 1, but " \ - "%.200s found", Py_TYPE(c)->tp_name); - return NULL; - } - - PyErr_Format(PyExc_TypeError, - "ord() expected a character, " - "but string of length %zd found", - size); - return NULL; -} - - -/*[clinic input] -pow as builtin_pow - - base: object - exp: object - mod: object = None - -Equivalent to base**exp with 2 arguments or base**exp % mod with 3 arguments - -Some types, such as ints, are able to use a more efficient algorithm when -invoked using the three argument form. -[clinic start generated code]*/ - -static PyObject * -builtin_pow_impl(PyObject *module, PyObject *base, PyObject *exp, - PyObject *mod) -/*[clinic end generated code: output=3ca1538221bbf15f input=435dbd48a12efb23]*/ -{ - return PyNumber_Power(base, exp, mod); -} - - -/* AC: cannot convert yet, waiting for *args support */ -static PyObject * -builtin_print(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - static const char * const _keywords[] = {"sep", "end", "file", "flush", 0}; - static struct _PyArg_Parser _parser = {"|OOOp:print", _keywords, 0}; - PyObject *sep = NULL, *end = NULL, *file = NULL; - int flush = 0; - int i, err; - - if (kwnames != NULL && - !_PyArg_ParseStackAndKeywords(args + nargs, 0, kwnames, &_parser, - &sep, &end, &file, &flush)) { - return NULL; - } - - if (file == NULL || file == Py_None) { - file = _PySys_GetObjectId(&PyId_stdout); - if (file == NULL) { - PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout"); - return NULL; - } - - /* sys.stdout may be None when FILE* stdout isn't connected */ - if (file == Py_None) - Py_RETURN_NONE; - } - - if (sep == Py_None) { - sep = NULL; - } - else if (sep && !PyUnicode_Check(sep)) { - PyErr_Format(PyExc_TypeError, - "sep must be None or a string, not %.200s", - Py_TYPE(sep)->tp_name); - return NULL; - } - if (end == Py_None) { - end = NULL; - } - else if (end && !PyUnicode_Check(end)) { - PyErr_Format(PyExc_TypeError, - "end must be None or a string, not %.200s", - Py_TYPE(end)->tp_name); - return NULL; - } - - for (i = 0; i < nargs; i++) { - if (i > 0) { - if (sep == NULL) - err = PyFile_WriteString(" ", file); - else - err = PyFile_WriteObject(sep, file, - Py_PRINT_RAW); - if (err) - return NULL; - } - err = PyFile_WriteObject(args[i], file, Py_PRINT_RAW); - if (err) - return NULL; - } - - if (end == NULL) - err = PyFile_WriteString("\n", file); - else - err = PyFile_WriteObject(end, file, Py_PRINT_RAW); - if (err) - return NULL; - - if (flush) { - PyObject *tmp = _PyObject_CallMethodIdNoArgs(file, &PyId_flush); - if (tmp == NULL) - return NULL; - Py_DECREF(tmp); - } - - Py_RETURN_NONE; -} - -PyDoc_STRVAR(print_doc, -"print(value, ..., sep=' ', end='\\n', file=sys.stdout, flush=False)\n\ -\n\ -Prints the values to a stream, or to sys.stdout by default.\n\ -Optional keyword arguments:\n\ -file: a file-like object (stream); defaults to the current sys.stdout.\n\ -sep: string inserted between values, default a space.\n\ -end: string appended after the last value, default a newline.\n\ -flush: whether to forcibly flush the stream."); - - -/*[clinic input] -input as builtin_input - - prompt: object(c_default="NULL") = None - / - -Read a string from standard input. The trailing newline is stripped. - -The prompt string, if given, is printed to standard output without a -trailing newline before reading input. - -If the user hits EOF (*nix: Ctrl-D, Windows: Ctrl-Z+Return), raise EOFError. -On *nix systems, readline is used if available. -[clinic start generated code]*/ - -static PyObject * -builtin_input_impl(PyObject *module, PyObject *prompt) -/*[clinic end generated code: output=83db5a191e7a0d60 input=5e8bb70c2908fe3c]*/ -{ - PyObject *fin = _PySys_GetObjectId(&PyId_stdin); - PyObject *fout = _PySys_GetObjectId(&PyId_stdout); - PyObject *ferr = _PySys_GetObjectId(&PyId_stderr); - PyObject *tmp; - long fd; - int tty; - - /* Check that stdin/out/err are intact */ - if (fin == NULL || fin == Py_None) { - PyErr_SetString(PyExc_RuntimeError, - "input(): lost sys.stdin"); - return NULL; - } - if (fout == NULL || fout == Py_None) { - PyErr_SetString(PyExc_RuntimeError, - "input(): lost sys.stdout"); - return NULL; - } - if (ferr == NULL || ferr == Py_None) { - PyErr_SetString(PyExc_RuntimeError, - "input(): lost sys.stderr"); - return NULL; - } - - if (PySys_Audit("builtins.input", "O", prompt ? prompt : Py_None) < 0) { - return NULL; - } - - /* First of all, flush stderr */ - tmp = _PyObject_CallMethodIdNoArgs(ferr, &PyId_flush); - if (tmp == NULL) - PyErr_Clear(); - else - Py_DECREF(tmp); - - /* We should only use (GNU) readline if Python's sys.stdin and - sys.stdout are the same as C's stdin and stdout, because we - need to pass it those. */ - tmp = _PyObject_CallMethodIdNoArgs(fin, &PyId_fileno); - if (tmp == NULL) { - PyErr_Clear(); - tty = 0; - } - else { - fd = PyLong_AsLong(tmp); - Py_DECREF(tmp); - if (fd < 0 && PyErr_Occurred()) - return NULL; - tty = fd == fileno(stdin) && isatty(fd); - } - if (tty) { - tmp = _PyObject_CallMethodIdNoArgs(fout, &PyId_fileno); - if (tmp == NULL) { - PyErr_Clear(); - tty = 0; - } - else { - fd = PyLong_AsLong(tmp); - Py_DECREF(tmp); - if (fd < 0 && PyErr_Occurred()) - return NULL; - tty = fd == fileno(stdout) && isatty(fd); - } - } - - /* If we're interactive, use (GNU) readline */ - if (tty) { - PyObject *po = NULL; - const char *promptstr; - char *s = NULL; - PyObject *stdin_encoding = NULL, *stdin_errors = NULL; - PyObject *stdout_encoding = NULL, *stdout_errors = NULL; - const char *stdin_encoding_str, *stdin_errors_str; - PyObject *result; - size_t len; - - /* stdin is a text stream, so it must have an encoding. */ - stdin_encoding = _PyObject_GetAttrId(fin, &PyId_encoding); - stdin_errors = _PyObject_GetAttrId(fin, &PyId_errors); - if (!stdin_encoding || !stdin_errors || - !PyUnicode_Check(stdin_encoding) || - !PyUnicode_Check(stdin_errors)) { - tty = 0; - goto _readline_errors; - } - stdin_encoding_str = PyUnicode_AsUTF8(stdin_encoding); - stdin_errors_str = PyUnicode_AsUTF8(stdin_errors); - if (!stdin_encoding_str || !stdin_errors_str) - goto _readline_errors; - tmp = _PyObject_CallMethodIdNoArgs(fout, &PyId_flush); - if (tmp == NULL) - PyErr_Clear(); - else - Py_DECREF(tmp); - if (prompt != NULL) { - /* We have a prompt, encode it as stdout would */ - const char *stdout_encoding_str, *stdout_errors_str; - PyObject *stringpo; - stdout_encoding = _PyObject_GetAttrId(fout, &PyId_encoding); - stdout_errors = _PyObject_GetAttrId(fout, &PyId_errors); - if (!stdout_encoding || !stdout_errors || - !PyUnicode_Check(stdout_encoding) || - !PyUnicode_Check(stdout_errors)) { - tty = 0; - goto _readline_errors; - } - stdout_encoding_str = PyUnicode_AsUTF8(stdout_encoding); - stdout_errors_str = PyUnicode_AsUTF8(stdout_errors); - if (!stdout_encoding_str || !stdout_errors_str) - goto _readline_errors; - stringpo = PyObject_Str(prompt); - if (stringpo == NULL) - goto _readline_errors; - po = PyUnicode_AsEncodedString(stringpo, - stdout_encoding_str, stdout_errors_str); - Py_CLEAR(stdout_encoding); - Py_CLEAR(stdout_errors); - Py_CLEAR(stringpo); - if (po == NULL) - goto _readline_errors; - assert(PyBytes_Check(po)); - promptstr = PyBytes_AS_STRING(po); - } - else { - po = NULL; - promptstr = ""; - } - s = PyOS_Readline(stdin, stdout, promptstr); - if (s == NULL) { - PyErr_CheckSignals(); - if (!PyErr_Occurred()) - PyErr_SetNone(PyExc_KeyboardInterrupt); - goto _readline_errors; - } - - len = strlen(s); - if (len == 0) { - PyErr_SetNone(PyExc_EOFError); - result = NULL; - } - else { - if (len > PY_SSIZE_T_MAX) { - PyErr_SetString(PyExc_OverflowError, - "input: input too long"); - result = NULL; - } - else { - len--; /* strip trailing '\n' */ - if (len != 0 && s[len-1] == '\r') - len--; /* strip trailing '\r' */ - result = PyUnicode_Decode(s, len, stdin_encoding_str, - stdin_errors_str); - } - } - Py_DECREF(stdin_encoding); - Py_DECREF(stdin_errors); - Py_XDECREF(po); - PyMem_Free(s); - - if (result != NULL) { - if (PySys_Audit("builtins.input/result", "O", result) < 0) { - return NULL; - } - } - - return result; - - _readline_errors: - Py_XDECREF(stdin_encoding); - Py_XDECREF(stdout_encoding); - Py_XDECREF(stdin_errors); - Py_XDECREF(stdout_errors); - Py_XDECREF(po); - if (tty) - return NULL; - - PyErr_Clear(); - } - - /* Fallback if we're not interactive */ - if (prompt != NULL) { - if (PyFile_WriteObject(prompt, fout, Py_PRINT_RAW) != 0) - return NULL; - } - tmp = _PyObject_CallMethodIdNoArgs(fout, &PyId_flush); - if (tmp == NULL) - PyErr_Clear(); - else - Py_DECREF(tmp); - return PyFile_GetLine(fin, -1); -} - - -/*[clinic input] -repr as builtin_repr - - obj: object - / - -Return the canonical string representation of the object. - -For many object types, including most builtins, eval(repr(obj)) == obj. -[clinic start generated code]*/ - -static PyObject * -builtin_repr(PyObject *module, PyObject *obj) -/*[clinic end generated code: output=7ed3778c44fd0194 input=1c9e6d66d3e3be04]*/ -{ - return PyObject_Repr(obj); -} - - -/*[clinic input] -round as builtin_round - - number: object - ndigits: object = None - -Round a number to a given precision in decimal digits. - -The return value is an integer if ndigits is omitted or None. Otherwise -the return value has the same type as the number. ndigits may be negative. -[clinic start generated code]*/ - -static PyObject * -builtin_round_impl(PyObject *module, PyObject *number, PyObject *ndigits) -/*[clinic end generated code: output=ff0d9dd176c02ede input=275678471d7aca15]*/ -{ - PyObject *round, *result; - - if (Py_TYPE(number)->tp_dict == NULL) { - if (PyType_Ready(Py_TYPE(number)) < 0) - return NULL; - } - - round = _PyObject_LookupSpecial(number, &PyId___round__); - if (round == NULL) { - if (!PyErr_Occurred()) - PyErr_Format(PyExc_TypeError, - "type %.100s doesn't define __round__ method", - Py_TYPE(number)->tp_name); - return NULL; - } - - if (ndigits == Py_None) - result = _PyObject_CallNoArg(round); - else - result = PyObject_CallOneArg(round, ndigits); - Py_DECREF(round); - return result; -} - - -/*AC: we need to keep the kwds dict intact to easily call into the - * list.sort method, which isn't currently supported in AC. So we just use - * the initially generated signature with a custom implementation. - */ -/* [disabled clinic input] -sorted as builtin_sorted - - iterable as seq: object - key as keyfunc: object = None - reverse: object = False - -Return a new list containing all items from the iterable in ascending order. - -A custom key function can be supplied to customize the sort order, and the -reverse flag can be set to request the result in descending order. -[end disabled clinic input]*/ - -PyDoc_STRVAR(builtin_sorted__doc__, -"sorted($module, iterable, /, *, key=None, reverse=False)\n" -"--\n" -"\n" -"Return a new list containing all items from the iterable in ascending order.\n" -"\n" -"A custom key function can be supplied to customize the sort order, and the\n" -"reverse flag can be set to request the result in descending order."); - -#define BUILTIN_SORTED_METHODDEF \ - {"sorted", (PyCFunction)(void(*)(void))builtin_sorted, METH_FASTCALL | METH_KEYWORDS, builtin_sorted__doc__}, - -static PyObject * -builtin_sorted(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *newlist, *v, *seq, *callable; - - /* Keyword arguments are passed through list.sort() which will check - them. */ - if (!_PyArg_UnpackStack(args, nargs, "sorted", 1, 1, &seq)) - return NULL; - - newlist = PySequence_List(seq); - if (newlist == NULL) - return NULL; - - callable = _PyObject_GetAttrId(newlist, &PyId_sort); - if (callable == NULL) { - Py_DECREF(newlist); - return NULL; - } - - assert(nargs >= 1); - v = PyObject_Vectorcall(callable, args + 1, nargs - 1, kwnames); - Py_DECREF(callable); - if (v == NULL) { - Py_DECREF(newlist); - return NULL; - } - Py_DECREF(v); - return newlist; -} - - -/* AC: cannot convert yet, as needs PEP 457 group support in inspect */ -static PyObject * -builtin_vars(PyObject *self, PyObject *args) -{ - PyObject *v = NULL; - PyObject *d; - - if (!PyArg_UnpackTuple(args, "vars", 0, 1, &v)) - return NULL; - if (v == NULL) { - d = PyEval_GetLocals(); - Py_XINCREF(d); - } - else { - if (_PyObject_LookupAttrId(v, &PyId___dict__, &d) == 0) { - PyErr_SetString(PyExc_TypeError, - "vars() argument must have __dict__ attribute"); - } - } - return d; -} - -PyDoc_STRVAR(vars_doc, -"vars([object]) -> dictionary\n\ -\n\ -Without arguments, equivalent to locals().\n\ -With an argument, equivalent to object.__dict__."); - - -/*[clinic input] -sum as builtin_sum - - iterable: object - / - start: object(c_default="NULL") = 0 - -Return the sum of a 'start' value (default: 0) plus an iterable of numbers - -When the iterable is empty, return the start value. -This function is intended specifically for use with numeric values and may -reject non-numeric types. -[clinic start generated code]*/ - -static PyObject * -builtin_sum_impl(PyObject *module, PyObject *iterable, PyObject *start) -/*[clinic end generated code: output=df758cec7d1d302f input=162b50765250d222]*/ -{ - PyObject *result = start; - PyObject *temp, *item, *iter; - - iter = PyObject_GetIter(iterable); - if (iter == NULL) - return NULL; - - if (result == NULL) { - result = PyLong_FromLong(0); - if (result == NULL) { - Py_DECREF(iter); - return NULL; - } - } else { - /* reject string values for 'start' parameter */ - if (PyUnicode_Check(result)) { - PyErr_SetString(PyExc_TypeError, - "sum() can't sum strings [use ''.join(seq) instead]"); - Py_DECREF(iter); - return NULL; - } - if (PyBytes_Check(result)) { - PyErr_SetString(PyExc_TypeError, - "sum() can't sum bytes [use b''.join(seq) instead]"); - Py_DECREF(iter); - return NULL; - } - if (PyByteArray_Check(result)) { - PyErr_SetString(PyExc_TypeError, - "sum() can't sum bytearray [use b''.join(seq) instead]"); - Py_DECREF(iter); - return NULL; - } - Py_INCREF(result); - } - -#ifndef SLOW_SUM - /* Fast addition by keeping temporary sums in C instead of new Python objects. - Assumes all inputs are the same type. If the assumption fails, default - to the more general routine. - */ - if (PyLong_CheckExact(result)) { - int overflow; - long i_result = PyLong_AsLongAndOverflow(result, &overflow); - /* If this already overflowed, don't even enter the loop. */ - if (overflow == 0) { - Py_DECREF(result); - result = NULL; - } - while(result == NULL) { - item = PyIter_Next(iter); - if (item == NULL) { - Py_DECREF(iter); - if (PyErr_Occurred()) - return NULL; - return PyLong_FromLong(i_result); - } - if (PyLong_CheckExact(item) || PyBool_Check(item)) { - long b = PyLong_AsLongAndOverflow(item, &overflow); - if (overflow == 0 && - (i_result >= 0 ? (b <= LONG_MAX - i_result) - : (b >= LONG_MIN - i_result))) - { - i_result += b; - Py_DECREF(item); - continue; - } - } - /* Either overflowed or is not an int. Restore real objects and process normally */ - result = PyLong_FromLong(i_result); - if (result == NULL) { - Py_DECREF(item); - Py_DECREF(iter); - return NULL; - } - temp = PyNumber_Add(result, item); - Py_DECREF(result); - Py_DECREF(item); - result = temp; - if (result == NULL) { - Py_DECREF(iter); - return NULL; - } - } - } - - if (PyFloat_CheckExact(result)) { - double f_result = PyFloat_AS_DOUBLE(result); - Py_DECREF(result); - result = NULL; - while(result == NULL) { - item = PyIter_Next(iter); - if (item == NULL) { - Py_DECREF(iter); - if (PyErr_Occurred()) - return NULL; - return PyFloat_FromDouble(f_result); - } - if (PyFloat_CheckExact(item)) { - f_result += PyFloat_AS_DOUBLE(item); - Py_DECREF(item); - continue; - } - if (PyLong_Check(item)) { - long value; - int overflow; - value = PyLong_AsLongAndOverflow(item, &overflow); - if (!overflow) { - f_result += (double)value; - Py_DECREF(item); - continue; - } - } - result = PyFloat_FromDouble(f_result); - if (result == NULL) { - Py_DECREF(item); - Py_DECREF(iter); - return NULL; - } - temp = PyNumber_Add(result, item); - Py_DECREF(result); - Py_DECREF(item); - result = temp; - if (result == NULL) { - Py_DECREF(iter); - return NULL; - } - } - } -#endif - - for(;;) { - item = PyIter_Next(iter); - if (item == NULL) { - /* error, or end-of-sequence */ - if (PyErr_Occurred()) { - Py_DECREF(result); - result = NULL; - } - break; - } - /* It's tempting to use PyNumber_InPlaceAdd instead of - PyNumber_Add here, to avoid quadratic running time - when doing 'sum(list_of_lists, [])'. However, this - would produce a change in behaviour: a snippet like - - empty = [] - sum([[x] for x in range(10)], empty) - - would change the value of empty. In fact, using - in-place addition rather that binary addition for - any of the steps introduces subtle behavior changes: - - https://bugs.python.org/issue18305 */ - temp = PyNumber_Add(result, item); - Py_DECREF(result); - Py_DECREF(item); - result = temp; - if (result == NULL) - break; - } - Py_DECREF(iter); - return result; -} - - -/*[clinic input] -isinstance as builtin_isinstance - - obj: object - class_or_tuple: object - / - -Return whether an object is an instance of a class or of a subclass thereof. - -A tuple, as in ``isinstance(x, (A, B, ...))``, may be given as the target to -check against. This is equivalent to ``isinstance(x, A) or isinstance(x, B) -or ...`` etc. -[clinic start generated code]*/ - -static PyObject * -builtin_isinstance_impl(PyObject *module, PyObject *obj, - PyObject *class_or_tuple) -/*[clinic end generated code: output=6faf01472c13b003 input=ffa743db1daf7549]*/ -{ - int retval; - - retval = PyObject_IsInstance(obj, class_or_tuple); - if (retval < 0) - return NULL; - return PyBool_FromLong(retval); -} - - -/*[clinic input] -issubclass as builtin_issubclass - - cls: object - class_or_tuple: object - / - -Return whether 'cls' is derived from another class or is the same class. - -A tuple, as in ``issubclass(x, (A, B, ...))``, may be given as the target to -check against. This is equivalent to ``issubclass(x, A) or issubclass(x, B) -or ...``. -[clinic start generated code]*/ - -static PyObject * -builtin_issubclass_impl(PyObject *module, PyObject *cls, - PyObject *class_or_tuple) -/*[clinic end generated code: output=358412410cd7a250 input=a24b9f3d58c370d6]*/ -{ - int retval; - - retval = PyObject_IsSubclass(cls, class_or_tuple); - if (retval < 0) - return NULL; - return PyBool_FromLong(retval); -} - - -typedef struct { - PyObject_HEAD - Py_ssize_t tuplesize; - PyObject *ittuple; /* tuple of iterators */ - PyObject *result; - int strict; -} zipobject; - -static PyObject * -zip_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - zipobject *lz; - Py_ssize_t i; - PyObject *ittuple; /* tuple of iterators */ - PyObject *result; - Py_ssize_t tuplesize; - int strict = 0; - - if (kwds) { - PyObject *empty = PyTuple_New(0); - if (empty == NULL) { - return NULL; - } - static char *kwlist[] = {"strict", NULL}; - int parsed = PyArg_ParseTupleAndKeywords( - empty, kwds, "|$p:zip", kwlist, &strict); - Py_DECREF(empty); - if (!parsed) { - return NULL; - } - } - - /* args must be a tuple */ - assert(PyTuple_Check(args)); - tuplesize = PyTuple_GET_SIZE(args); - - /* obtain iterators */ - ittuple = PyTuple_New(tuplesize); - if (ittuple == NULL) - return NULL; - for (i=0; i < tuplesize; ++i) { - PyObject *item = PyTuple_GET_ITEM(args, i); - PyObject *it = PyObject_GetIter(item); - if (it == NULL) { - Py_DECREF(ittuple); - return NULL; - } - PyTuple_SET_ITEM(ittuple, i, it); - } - - /* create a result holder */ - result = PyTuple_New(tuplesize); - if (result == NULL) { - Py_DECREF(ittuple); - return NULL; - } - for (i=0 ; i < tuplesize ; i++) { - Py_INCREF(Py_None); - PyTuple_SET_ITEM(result, i, Py_None); - } - - /* create zipobject structure */ - lz = (zipobject *)type->tp_alloc(type, 0); - if (lz == NULL) { - Py_DECREF(ittuple); - Py_DECREF(result); - return NULL; - } - lz->ittuple = ittuple; - lz->tuplesize = tuplesize; - lz->result = result; - lz->strict = strict; - - return (PyObject *)lz; -} - -static void -zip_dealloc(zipobject *lz) -{ - PyObject_GC_UnTrack(lz); - Py_XDECREF(lz->ittuple); - Py_XDECREF(lz->result); - Py_TYPE(lz)->tp_free(lz); -} - -static int -zip_traverse(zipobject *lz, visitproc visit, void *arg) -{ - Py_VISIT(lz->ittuple); - Py_VISIT(lz->result); - return 0; -} - -static PyObject * -zip_next(zipobject *lz) -{ - Py_ssize_t i; - Py_ssize_t tuplesize = lz->tuplesize; - PyObject *result = lz->result; - PyObject *it; - PyObject *item; - PyObject *olditem; - - if (tuplesize == 0) - return NULL; - if (Py_REFCNT(result) == 1) { - Py_INCREF(result); - for (i=0 ; i < tuplesize ; i++) { - it = PyTuple_GET_ITEM(lz->ittuple, i); - item = (*Py_TYPE(it)->tp_iternext)(it); - if (item == NULL) { - Py_DECREF(result); - if (lz->strict) { - goto check; - } - return NULL; - } - olditem = PyTuple_GET_ITEM(result, i); - PyTuple_SET_ITEM(result, i, item); - Py_DECREF(olditem); - } - // bpo-42536: The GC may have untracked this result tuple. Since we're - // recycling it, make sure it's tracked again: - if (!_PyObject_GC_IS_TRACKED(result)) { - _PyObject_GC_TRACK(result); - } - } else { - result = PyTuple_New(tuplesize); - if (result == NULL) - return NULL; - for (i=0 ; i < tuplesize ; i++) { - it = PyTuple_GET_ITEM(lz->ittuple, i); - item = (*Py_TYPE(it)->tp_iternext)(it); - if (item == NULL) { - Py_DECREF(result); - if (lz->strict) { - goto check; - } - return NULL; - } - PyTuple_SET_ITEM(result, i, item); - } - } - return result; -check: - if (PyErr_Occurred()) { - if (!PyErr_ExceptionMatches(PyExc_StopIteration)) { - // next() on argument i raised an exception (not StopIteration) - return NULL; - } - PyErr_Clear(); - } - if (i) { - // ValueError: zip() argument 2 is shorter than argument 1 - // ValueError: zip() argument 3 is shorter than arguments 1-2 - const char* plural = i == 1 ? " " : "s 1-"; - return PyErr_Format(PyExc_ValueError, - "zip() argument %d is shorter than argument%s%d", - i + 1, plural, i); - } - for (i = 1; i < tuplesize; i++) { - it = PyTuple_GET_ITEM(lz->ittuple, i); - item = (*Py_TYPE(it)->tp_iternext)(it); - if (item) { - Py_DECREF(item); - const char* plural = i == 1 ? " " : "s 1-"; - return PyErr_Format(PyExc_ValueError, - "zip() argument %d is longer than argument%s%d", - i + 1, plural, i); - } - if (PyErr_Occurred()) { - if (!PyErr_ExceptionMatches(PyExc_StopIteration)) { - // next() on argument i raised an exception (not StopIteration) - return NULL; - } - PyErr_Clear(); - } - // Argument i is exhausted. So far so good... - } - // All arguments are exhausted. Success! - return NULL; -} - -static PyObject * -zip_reduce(zipobject *lz, PyObject *Py_UNUSED(ignored)) -{ - /* Just recreate the zip with the internal iterator tuple */ - if (lz->strict) { - return PyTuple_Pack(3, Py_TYPE(lz), lz->ittuple, Py_True); - } - return PyTuple_Pack(2, Py_TYPE(lz), lz->ittuple); -} - -PyDoc_STRVAR(setstate_doc, "Set state information for unpickling."); - -static PyObject * -zip_setstate(zipobject *lz, PyObject *state) -{ - int strict = PyObject_IsTrue(state); - if (strict < 0) { - return NULL; - } - lz->strict = strict; - Py_RETURN_NONE; -} - -static PyMethodDef zip_methods[] = { - {"__reduce__", (PyCFunction)zip_reduce, METH_NOARGS, reduce_doc}, - {"__setstate__", (PyCFunction)zip_setstate, METH_O, setstate_doc}, - {NULL} /* sentinel */ -}; - -PyDoc_STRVAR(zip_doc, -"zip(*iterables, strict=False) --> Yield tuples until an input is exhausted.\n\ -\n\ - >>> list(zip('abcdefg', range(3), range(4)))\n\ - [('a', 0, 0), ('b', 1, 1), ('c', 2, 2)]\n\ -\n\ -The zip object yields n-length tuples, where n is the number of iterables\n\ -passed as positional arguments to zip(). The i-th element in every tuple\n\ -comes from the i-th iterable argument to zip(). This continues until the\n\ -shortest argument is exhausted.\n\ -\n\ -If strict is true and one of the arguments is exhausted before the others,\n\ -raise a ValueError."); - -PyTypeObject PyZip_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "zip", /* tp_name */ - sizeof(zipobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)zip_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ - zip_doc, /* tp_doc */ - (traverseproc)zip_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)zip_next, /* tp_iternext */ - zip_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - PyType_GenericAlloc, /* tp_alloc */ - zip_new, /* tp_new */ - PyObject_GC_Del, /* tp_free */ -}; - - -static PyMethodDef builtin_methods[] = { - {"__build_class__", (PyCFunction)(void(*)(void))builtin___build_class__, - METH_FASTCALL | METH_KEYWORDS, build_class_doc}, - {"__import__", (PyCFunction)(void(*)(void))builtin___import__, METH_VARARGS | METH_KEYWORDS, import_doc}, - BUILTIN_ABS_METHODDEF - BUILTIN_ALL_METHODDEF - BUILTIN_ANY_METHODDEF - BUILTIN_ASCII_METHODDEF - BUILTIN_BIN_METHODDEF - {"breakpoint", (PyCFunction)(void(*)(void))builtin_breakpoint, METH_FASTCALL | METH_KEYWORDS, breakpoint_doc}, - BUILTIN_CALLABLE_METHODDEF - BUILTIN_CHR_METHODDEF - BUILTIN_COMPILE_METHODDEF - BUILTIN_DELATTR_METHODDEF - {"dir", builtin_dir, METH_VARARGS, dir_doc}, - BUILTIN_DIVMOD_METHODDEF - BUILTIN_EVAL_METHODDEF - BUILTIN_EXEC_METHODDEF - BUILTIN_FORMAT_METHODDEF - {"getattr", (PyCFunction)(void(*)(void))builtin_getattr, METH_FASTCALL, getattr_doc}, - BUILTIN_GLOBALS_METHODDEF - BUILTIN_HASATTR_METHODDEF - BUILTIN_HASH_METHODDEF - BUILTIN_HEX_METHODDEF - BUILTIN_ID_METHODDEF - BUILTIN_INPUT_METHODDEF - BUILTIN_ISINSTANCE_METHODDEF - BUILTIN_ISSUBCLASS_METHODDEF - {"iter", (PyCFunction)(void(*)(void))builtin_iter, METH_FASTCALL, iter_doc}, - BUILTIN_AITER_METHODDEF - BUILTIN_LEN_METHODDEF - BUILTIN_LOCALS_METHODDEF - {"max", (PyCFunction)(void(*)(void))builtin_max, METH_VARARGS | METH_KEYWORDS, max_doc}, - {"min", (PyCFunction)(void(*)(void))builtin_min, METH_VARARGS | METH_KEYWORDS, min_doc}, - {"next", (PyCFunction)(void(*)(void))builtin_next, METH_FASTCALL, next_doc}, - BUILTIN_ANEXT_METHODDEF - BUILTIN_OCT_METHODDEF - BUILTIN_ORD_METHODDEF - BUILTIN_POW_METHODDEF - {"print", (PyCFunction)(void(*)(void))builtin_print, METH_FASTCALL | METH_KEYWORDS, print_doc}, - BUILTIN_REPR_METHODDEF - BUILTIN_ROUND_METHODDEF - BUILTIN_SETATTR_METHODDEF - BUILTIN_SORTED_METHODDEF - BUILTIN_SUM_METHODDEF - {"vars", builtin_vars, METH_VARARGS, vars_doc}, - {NULL, NULL}, -}; - -PyDoc_STRVAR(builtin_doc, -"Built-in functions, exceptions, and other objects.\n\ -\n\ -Noteworthy: None is the `nil' object; Ellipsis represents `...' in slices."); - -static struct PyModuleDef builtinsmodule = { - PyModuleDef_HEAD_INIT, - "builtins", - builtin_doc, - -1, /* multiple "initialization" just copies the module dict. */ - builtin_methods, - NULL, - NULL, - NULL, - NULL -}; - - -PyObject * -_PyBuiltin_Init(PyInterpreterState *interp) -{ - PyObject *mod, *dict, *debug; - - const PyConfig *config = _PyInterpreterState_GetConfig(interp); - - if (PyType_Ready(&PyFilter_Type) < 0 || - PyType_Ready(&PyMap_Type) < 0 || - PyType_Ready(&PyZip_Type) < 0) - return NULL; - - mod = _PyModule_CreateInitialized(&builtinsmodule, PYTHON_API_VERSION); - if (mod == NULL) - return NULL; - dict = PyModule_GetDict(mod); - -#ifdef Py_TRACE_REFS - /* "builtins" exposes a number of statically allocated objects - * that, before this code was added in 2.3, never showed up in - * the list of "all objects" maintained by Py_TRACE_REFS. As a - * result, programs leaking references to None and False (etc) - * couldn't be diagnosed by examining sys.getobjects(0). - */ -#define ADD_TO_ALL(OBJECT) _Py_AddToAllObjects((PyObject *)(OBJECT), 0) -#else -#define ADD_TO_ALL(OBJECT) (void)0 -#endif - -#define SETBUILTIN(NAME, OBJECT) \ - if (PyDict_SetItemString(dict, NAME, (PyObject *)OBJECT) < 0) \ - return NULL; \ - ADD_TO_ALL(OBJECT) - - SETBUILTIN("None", Py_None); - SETBUILTIN("Ellipsis", Py_Ellipsis); - SETBUILTIN("NotImplemented", Py_NotImplemented); - SETBUILTIN("False", Py_False); - SETBUILTIN("True", Py_True); - SETBUILTIN("bool", &PyBool_Type); - SETBUILTIN("memoryview", &PyMemoryView_Type); - SETBUILTIN("bytearray", &PyByteArray_Type); - SETBUILTIN("bytes", &PyBytes_Type); - SETBUILTIN("classmethod", &PyClassMethod_Type); - SETBUILTIN("complex", &PyComplex_Type); - SETBUILTIN("dict", &PyDict_Type); - SETBUILTIN("enumerate", &PyEnum_Type); - SETBUILTIN("filter", &PyFilter_Type); - SETBUILTIN("float", &PyFloat_Type); - SETBUILTIN("frozenset", &PyFrozenSet_Type); - SETBUILTIN("property", &PyProperty_Type); - SETBUILTIN("int", &PyLong_Type); - SETBUILTIN("list", &PyList_Type); - SETBUILTIN("map", &PyMap_Type); - SETBUILTIN("object", &PyBaseObject_Type); - SETBUILTIN("range", &PyRange_Type); - SETBUILTIN("reversed", &PyReversed_Type); - SETBUILTIN("set", &PySet_Type); - SETBUILTIN("slice", &PySlice_Type); - SETBUILTIN("staticmethod", &PyStaticMethod_Type); - SETBUILTIN("str", &PyUnicode_Type); - SETBUILTIN("super", &PySuper_Type); - SETBUILTIN("tuple", &PyTuple_Type); - SETBUILTIN("type", &PyType_Type); - SETBUILTIN("zip", &PyZip_Type); - debug = PyBool_FromLong(config->optimization_level == 0); - if (PyDict_SetItemString(dict, "__debug__", debug) < 0) { - Py_DECREF(debug); - return NULL; - } - Py_DECREF(debug); - - return mod; -#undef ADD_TO_ALL -#undef SETBUILTIN -} diff --git a/contrib/tools/python3/src/Python/bootstrap_hash.c b/contrib/tools/python3/src/Python/bootstrap_hash.c deleted file mode 100644 index 77ccbee18d4..00000000000 --- a/contrib/tools/python3/src/Python/bootstrap_hash.c +++ /dev/null @@ -1,628 +0,0 @@ -#include "Python.h" -#include "pycore_initconfig.h" -#ifdef MS_WINDOWS -# include <windows.h> -/* All sample MSDN wincrypt programs include the header below. It is at least - * required with Min GW. */ -# include <wincrypt.h> -#else -# include <fcntl.h> -# ifdef HAVE_SYS_STAT_H -# include <sys/stat.h> -# endif -# ifdef HAVE_LINUX_RANDOM_H -# include <linux/random.h> -# endif -# if defined(HAVE_SYS_RANDOM_H) && (defined(HAVE_GETRANDOM) || defined(HAVE_GETENTROPY)) -# include <sys/random.h> -# endif -# if !defined(HAVE_GETRANDOM) && defined(HAVE_GETRANDOM_SYSCALL) -# include <sys/syscall.h> -# endif -#endif - -#ifdef _Py_MEMORY_SANITIZER -# include <sanitizer/msan_interface.h> -#endif - -#if defined(__APPLE__) && defined(__has_builtin) -# if __has_builtin(__builtin_available) -# define HAVE_GETENTRYPY_GETRANDOM_RUNTIME __builtin_available(macOS 10.12, iOS 10.10, tvOS 10.0, watchOS 3.0, *) -# endif -#endif -#ifndef HAVE_GETENTRYPY_GETRANDOM_RUNTIME -# define HAVE_GETENTRYPY_GETRANDOM_RUNTIME 1 -#endif - - -#ifdef Py_DEBUG -int _Py_HashSecret_Initialized = 0; -#else -static int _Py_HashSecret_Initialized = 0; -#endif - -#ifdef MS_WINDOWS -static HCRYPTPROV hCryptProv = 0; - -static int -win32_urandom_init(int raise) -{ - /* Acquire context */ - if (!CryptAcquireContextW(&hCryptProv, NULL, NULL, - PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) - goto error; - - return 0; - -error: - if (raise) { - PyErr_SetFromWindowsErr(0); - } - return -1; -} - -/* Fill buffer with size pseudo-random bytes generated by the Windows CryptoGen - API. Return 0 on success, or raise an exception and return -1 on error. */ -static int -win32_urandom(unsigned char *buffer, Py_ssize_t size, int raise) -{ - if (hCryptProv == 0) - { - if (win32_urandom_init(raise) == -1) { - return -1; - } - } - - while (size > 0) - { - DWORD chunk = (DWORD)Py_MIN(size, PY_DWORD_MAX); - if (!CryptGenRandom(hCryptProv, chunk, buffer)) - { - /* CryptGenRandom() failed */ - if (raise) { - PyErr_SetFromWindowsErr(0); - } - return -1; - } - buffer += chunk; - size -= chunk; - } - return 0; -} - -#else /* !MS_WINDOWS */ - -#if defined(HAVE_GETRANDOM) || defined(HAVE_GETRANDOM_SYSCALL) -#define PY_GETRANDOM 1 - -/* Call getrandom() to get random bytes: - - - Return 1 on success - - Return 0 if getrandom() is not available (failed with ENOSYS or EPERM), - or if getrandom(GRND_NONBLOCK) failed with EAGAIN (system urandom not - initialized yet) and raise=0. - - Raise an exception (if raise is non-zero) and return -1 on error: - if getrandom() failed with EINTR, raise is non-zero and the Python signal - handler raised an exception, or if getrandom() failed with a different - error. - - getrandom() is retried if it failed with EINTR: interrupted by a signal. */ -static int -py_getrandom(void *buffer, Py_ssize_t size, int blocking, int raise) -{ - /* Is getrandom() supported by the running kernel? Set to 0 if getrandom() - failed with ENOSYS or EPERM. Need Linux kernel 3.17 or newer, or Solaris - 11.3 or newer */ - static int getrandom_works = 1; - int flags; - char *dest; - long n; - - if (!getrandom_works) { - return 0; - } - - flags = blocking ? 0 : GRND_NONBLOCK; - dest = buffer; - while (0 < size) { -#if defined(__sun) && defined(__SVR4) - /* Issue #26735: On Solaris, getrandom() is limited to returning up - to 1024 bytes. Call it multiple times if more bytes are - requested. */ - n = Py_MIN(size, 1024); -#else - n = Py_MIN(size, LONG_MAX); -#endif - - errno = 0; -#ifdef HAVE_GETRANDOM - if (raise) { - Py_BEGIN_ALLOW_THREADS - n = getrandom(dest, n, flags); - Py_END_ALLOW_THREADS - } - else { - n = getrandom(dest, n, flags); - } -# ifdef _Py_MEMORY_SANITIZER - if (n > 0) { - __msan_unpoison(dest, n); - } -# endif -#else - /* On Linux, use the syscall() function because the GNU libc doesn't - expose the Linux getrandom() syscall yet. See: - https://sourceware.org/bugzilla/show_bug.cgi?id=17252 */ - if (raise) { - Py_BEGIN_ALLOW_THREADS - n = syscall(SYS_getrandom, dest, n, flags); - Py_END_ALLOW_THREADS - } - else { - n = syscall(SYS_getrandom, dest, n, flags); - } -# ifdef _Py_MEMORY_SANITIZER - if (n > 0) { - __msan_unpoison(dest, n); - } -# endif -#endif - - if (n < 0) { - /* ENOSYS: the syscall is not supported by the kernel. - EPERM: the syscall is blocked by a security policy (ex: SECCOMP) - or something else. */ - if (errno == ENOSYS || errno == EPERM) { - getrandom_works = 0; - return 0; - } - - /* getrandom(GRND_NONBLOCK) fails with EAGAIN if the system urandom - is not initialized yet. For _PyRandom_Init(), we ignore the - error and fall back on reading /dev/urandom which never blocks, - even if the system urandom is not initialized yet: - see the PEP 524. */ - if (errno == EAGAIN && !raise && !blocking) { - return 0; - } - - if (errno == EINTR) { - if (raise) { - if (PyErr_CheckSignals()) { - return -1; - } - } - - /* retry getrandom() if it was interrupted by a signal */ - continue; - } - - if (raise) { - PyErr_SetFromErrno(PyExc_OSError); - } - return -1; - } - - dest += n; - size -= n; - } - return 1; -} - -#elif defined(HAVE_GETENTROPY) -#define PY_GETENTROPY 1 - -/* Fill buffer with size pseudo-random bytes generated by getentropy(): - - - Return 1 on success - - Return 0 if getentropy() syscall is not available (failed with ENOSYS or - EPERM). - - Raise an exception (if raise is non-zero) and return -1 on error: - if getentropy() failed with EINTR, raise is non-zero and the Python signal - handler raised an exception, or if getentropy() failed with a different - error. - - getentropy() is retried if it failed with EINTR: interrupted by a signal. */ - -#if defined(__APPLE__) && defined(__has_attribute) && __has_attribute(availability) -static int -py_getentropy(char *buffer, Py_ssize_t size, int raise) - __attribute__((availability(macos,introduced=10.12))) - __attribute__((availability(ios,introduced=10.0))) - __attribute__((availability(tvos,introduced=10.0))) - __attribute__((availability(watchos,introduced=3.0))); -#endif - -static int -py_getentropy(char *buffer, Py_ssize_t size, int raise) -{ - /* Is getentropy() supported by the running kernel? Set to 0 if - getentropy() failed with ENOSYS or EPERM. */ - static int getentropy_works = 1; - - if (!getentropy_works) { - return 0; - } - - while (size > 0) { - /* getentropy() is limited to returning up to 256 bytes. Call it - multiple times if more bytes are requested. */ - Py_ssize_t len = Py_MIN(size, 256); - int res; - - if (raise) { - Py_BEGIN_ALLOW_THREADS - res = getentropy(buffer, len); - Py_END_ALLOW_THREADS - } - else { - res = getentropy(buffer, len); - } - - if (res < 0) { - /* ENOSYS: the syscall is not supported by the running kernel. - EPERM: the syscall is blocked by a security policy (ex: SECCOMP) - or something else. */ - if (errno == ENOSYS || errno == EPERM) { - getentropy_works = 0; - return 0; - } - - if (errno == EINTR) { - if (raise) { - if (PyErr_CheckSignals()) { - return -1; - } - } - - /* retry getentropy() if it was interrupted by a signal */ - continue; - } - - if (raise) { - PyErr_SetFromErrno(PyExc_OSError); - } - return -1; - } - - buffer += len; - size -= len; - } - return 1; -} -#endif /* defined(HAVE_GETENTROPY) && !(defined(__sun) && defined(__SVR4)) */ - - -static struct { - int fd; - dev_t st_dev; - ino_t st_ino; -} urandom_cache = { -1 }; - -/* Read random bytes from the /dev/urandom device: - - - Return 0 on success - - Raise an exception (if raise is non-zero) and return -1 on error - - Possible causes of errors: - - - open() failed with ENOENT, ENXIO, ENODEV, EACCES: the /dev/urandom device - was not found. For example, it was removed manually or not exposed in a - chroot or container. - - open() failed with a different error - - fstat() failed - - read() failed or returned 0 - - read() is retried if it failed with EINTR: interrupted by a signal. - - The file descriptor of the device is kept open between calls to avoid using - many file descriptors when run in parallel from multiple threads: - see the issue #18756. - - st_dev and st_ino fields of the file descriptor (from fstat()) are cached to - check if the file descriptor was replaced by a different file (which is - likely a bug in the application): see the issue #21207. - - If the file descriptor was closed or replaced, open a new file descriptor - but don't close the old file descriptor: it probably points to something - important for some third-party code. */ -static int -dev_urandom(char *buffer, Py_ssize_t size, int raise) -{ - int fd; - Py_ssize_t n; - - if (raise) { - struct _Py_stat_struct st; - int fstat_result; - - if (urandom_cache.fd >= 0) { - Py_BEGIN_ALLOW_THREADS - fstat_result = _Py_fstat_noraise(urandom_cache.fd, &st); - Py_END_ALLOW_THREADS - - /* Does the fd point to the same thing as before? (issue #21207) */ - if (fstat_result - || st.st_dev != urandom_cache.st_dev - || st.st_ino != urandom_cache.st_ino) { - /* Something changed: forget the cached fd (but don't close it, - since it probably points to something important for some - third-party code). */ - urandom_cache.fd = -1; - } - } - if (urandom_cache.fd >= 0) - fd = urandom_cache.fd; - else { - fd = _Py_open("/dev/urandom", O_RDONLY); - if (fd < 0) { - if (errno == ENOENT || errno == ENXIO || - errno == ENODEV || errno == EACCES) { - PyErr_SetString(PyExc_NotImplementedError, - "/dev/urandom (or equivalent) not found"); - } - /* otherwise, keep the OSError exception raised by _Py_open() */ - return -1; - } - if (urandom_cache.fd >= 0) { - /* urandom_fd was initialized by another thread while we were - not holding the GIL, keep it. */ - close(fd); - fd = urandom_cache.fd; - } - else { - if (_Py_fstat(fd, &st)) { - close(fd); - return -1; - } - else { - urandom_cache.fd = fd; - urandom_cache.st_dev = st.st_dev; - urandom_cache.st_ino = st.st_ino; - } - } - } - - do { - n = _Py_read(fd, buffer, (size_t)size); - if (n == -1) - return -1; - if (n == 0) { - PyErr_Format(PyExc_RuntimeError, - "Failed to read %zi bytes from /dev/urandom", - size); - return -1; - } - - buffer += n; - size -= n; - } while (0 < size); - } - else { - fd = _Py_open_noraise("/dev/urandom", O_RDONLY); - if (fd < 0) { - return -1; - } - - while (0 < size) - { - do { - n = read(fd, buffer, (size_t)size); - } while (n < 0 && errno == EINTR); - - if (n <= 0) { - /* stop on error or if read(size) returned 0 */ - close(fd); - return -1; - } - - buffer += n; - size -= n; - } - close(fd); - } - return 0; -} - -static void -dev_urandom_close(void) -{ - if (urandom_cache.fd >= 0) { - close(urandom_cache.fd); - urandom_cache.fd = -1; - } -} -#endif /* !MS_WINDOWS */ - - -/* Fill buffer with pseudo-random bytes generated by a linear congruent - generator (LCG): - - x(n+1) = (x(n) * 214013 + 2531011) % 2^32 - - Use bits 23..16 of x(n) to generate a byte. */ -static void -lcg_urandom(unsigned int x0, unsigned char *buffer, size_t size) -{ - size_t index; - unsigned int x; - - x = x0; - for (index=0; index < size; index++) { - x *= 214013; - x += 2531011; - /* modulo 2 ^ (8 * sizeof(int)) */ - buffer[index] = (x >> 16) & 0xff; - } -} - -/* Read random bytes: - - - Return 0 on success - - Raise an exception (if raise is non-zero) and return -1 on error - - Used sources of entropy ordered by preference, preferred source first: - - - CryptGenRandom() on Windows - - getrandom() function (ex: Linux and Solaris): call py_getrandom() - - getentropy() function (ex: OpenBSD): call py_getentropy() - - /dev/urandom device - - Read from the /dev/urandom device if getrandom() or getentropy() function - is not available or does not work. - - Prefer getrandom() over getentropy() because getrandom() supports blocking - and non-blocking mode: see the PEP 524. Python requires non-blocking RNG at - startup to initialize its hash secret, but os.urandom() must block until the - system urandom is initialized (at least on Linux 3.17 and newer). - - Prefer getrandom() and getentropy() over reading directly /dev/urandom - because these functions don't need file descriptors and so avoid ENFILE or - EMFILE errors (too many open files): see the issue #18756. - - Only the getrandom() function supports non-blocking mode. - - Only use RNG running in the kernel. They are more secure because it is - harder to get the internal state of a RNG running in the kernel land than a - RNG running in the user land. The kernel has a direct access to the hardware - and has access to hardware RNG, they are used as entropy sources. - - Note: the OpenSSL RAND_pseudo_bytes() function does not automatically reseed - its RNG on fork(), two child processes (with the same pid) generate the same - random numbers: see issue #18747. Kernel RNGs don't have this issue, - they have access to good quality entropy sources. - - If raise is zero: - - - Don't raise an exception on error - - Don't call the Python signal handler (don't call PyErr_CheckSignals()) if - a function fails with EINTR: retry directly the interrupted function - - Don't release the GIL to call functions. -*/ -static int -pyurandom(void *buffer, Py_ssize_t size, int blocking, int raise) -{ -#if defined(PY_GETRANDOM) || defined(PY_GETENTROPY) - int res; -#endif - - if (size < 0) { - if (raise) { - PyErr_Format(PyExc_ValueError, - "negative argument not allowed"); - } - return -1; - } - - if (size == 0) { - return 0; - } - -#ifdef MS_WINDOWS - return win32_urandom((unsigned char *)buffer, size, raise); -#else - -#if defined(PY_GETRANDOM) || defined(PY_GETENTROPY) - if (HAVE_GETENTRYPY_GETRANDOM_RUNTIME) { -#ifdef PY_GETRANDOM - res = py_getrandom(buffer, size, blocking, raise); -#else - res = py_getentropy(buffer, size, raise); -#endif - if (res < 0) { - return -1; - } - if (res == 1) { - return 0; - } - /* getrandom() or getentropy() function is not available: failed with - ENOSYS or EPERM. Fall back on reading from /dev/urandom. */ - } /* end of availability block */ -#endif - - return dev_urandom(buffer, size, raise); -#endif -} - -/* Fill buffer with size pseudo-random bytes from the operating system random - number generator (RNG). It is suitable for most cryptographic purposes - except long living private keys for asymmetric encryption. - - On Linux 3.17 and newer, the getrandom() syscall is used in blocking mode: - block until the system urandom entropy pool is initialized (128 bits are - collected by the kernel). - - Return 0 on success. Raise an exception and return -1 on error. */ -int -_PyOS_URandom(void *buffer, Py_ssize_t size) -{ - return pyurandom(buffer, size, 1, 1); -} - -/* Fill buffer with size pseudo-random bytes from the operating system random - number generator (RNG). It is not suitable for cryptographic purpose. - - On Linux 3.17 and newer (when getrandom() syscall is used), if the system - urandom is not initialized yet, the function returns "weak" entropy read - from /dev/urandom. - - Return 0 on success. Raise an exception and return -1 on error. */ -int -_PyOS_URandomNonblock(void *buffer, Py_ssize_t size) -{ - return pyurandom(buffer, size, 0, 1); -} - - -PyStatus -_Py_HashRandomization_Init(const PyConfig *config) -{ - void *secret = &_Py_HashSecret; - Py_ssize_t secret_size = sizeof(_Py_HashSecret_t); - - if (_Py_HashSecret_Initialized) { - return _PyStatus_OK(); - } - _Py_HashSecret_Initialized = 1; - - if (config->use_hash_seed) { - if (config->hash_seed == 0) { - /* disable the randomized hash */ - memset(secret, 0, secret_size); - } - else { - /* use the specified hash seed */ - lcg_urandom(config->hash_seed, secret, secret_size); - } - } - else { - /* use a random hash seed */ - int res; - - /* _PyRandom_Init() is called very early in the Python initialization - and so exceptions cannot be used (use raise=0). - - _PyRandom_Init() must not block Python initialization: call - pyurandom() is non-blocking mode (blocking=0): see the PEP 524. */ - res = pyurandom(secret, secret_size, 0, 0); - if (res < 0) { - return _PyStatus_ERR("failed to get random numbers " - "to initialize Python"); - } - } - return _PyStatus_OK(); -} - - -void -_Py_HashRandomization_Fini(void) -{ -#ifdef MS_WINDOWS - if (hCryptProv) { - CryptReleaseContext(hCryptProv, 0); - hCryptProv = 0; - } -#else - dev_urandom_close(); -#endif -} diff --git a/contrib/tools/python3/src/Python/ceval.c b/contrib/tools/python3/src/Python/ceval.c deleted file mode 100644 index 9a193c994d1..00000000000 --- a/contrib/tools/python3/src/Python/ceval.c +++ /dev/null @@ -1,6507 +0,0 @@ -/* Execute compiled code */ - -/* XXX TO DO: - XXX speed up searching for keywords by using a dictionary - XXX document it! - */ - -/* enable more aggressive intra-module optimizations, where available */ -/* affects both release and debug builds - see bpo-43271 */ -#define PY_LOCAL_AGGRESSIVE - -#include "Python.h" -#include "pycore_abstract.h" // _PyIndex_Check() -#include "pycore_call.h" // _PyObject_FastCallDictTstate() -#include "pycore_ceval.h" // _PyEval_SignalAsyncExc() -#include "pycore_code.h" // _PyCode_InitOpcache() -#include "pycore_initconfig.h" // _PyStatus_OK() -#include "pycore_object.h" // _PyObject_GC_TRACK() -#include "pycore_pyerrors.h" // _PyErr_Fetch() -#include "pycore_pylifecycle.h" // _PyErr_Print() -#include "pycore_pymem.h" // _PyMem_IsPtrFreed() -#include "pycore_pystate.h" // _PyInterpreterState_GET() -#include "pycore_sysmodule.h" // _PySys_Audit() -#include "pycore_tuple.h" // _PyTuple_ITEMS() - -#include "code.h" -#include "dictobject.h" -#include "frameobject.h" -#include "opcode.h" -#include "pydtrace.h" -#include "setobject.h" -#include "structmember.h" // struct PyMemberDef, T_OFFSET_EX - -#include <ctype.h> - -typedef struct { - PyCodeObject *code; // The code object for the bounds. May be NULL. - PyCodeAddressRange bounds; // Only valid if code != NULL. - CFrame cframe; -} PyTraceInfo; - - -#ifdef Py_DEBUG -/* For debugging the interpreter: */ -#define LLTRACE 1 /* Low-level trace feature */ -#define CHECKEXC 1 /* Double-check exception checking */ -#endif - -#if !defined(Py_BUILD_CORE) -# error "ceval.c must be build with Py_BUILD_CORE define for best performance" -#endif - -_Py_IDENTIFIER(__name__); - -/* Forward declarations */ -Py_LOCAL_INLINE(PyObject *) call_function( - PyThreadState *tstate, PyTraceInfo *, PyObject ***pp_stack, - Py_ssize_t oparg, PyObject *kwnames); -static PyObject * do_call_core( - PyThreadState *tstate, PyTraceInfo *, PyObject *func, - PyObject *callargs, PyObject *kwdict); - -#ifdef LLTRACE -static int lltrace; -static int prtrace(PyThreadState *, PyObject *, const char *); -#endif -static int call_trace(Py_tracefunc, PyObject *, - PyThreadState *, PyFrameObject *, - PyTraceInfo *, - int, PyObject *); -static int call_trace_protected(Py_tracefunc, PyObject *, - PyThreadState *, PyFrameObject *, - PyTraceInfo *, - int, PyObject *); -static void call_exc_trace(Py_tracefunc, PyObject *, - PyThreadState *, PyFrameObject *, - PyTraceInfo *trace_info); -static int maybe_call_line_trace(Py_tracefunc, PyObject *, - PyThreadState *, PyFrameObject *, - PyTraceInfo *, int); -static void maybe_dtrace_line(PyFrameObject *, PyTraceInfo *, int); -static void dtrace_function_entry(PyFrameObject *); -static void dtrace_function_return(PyFrameObject *); - -static PyObject * import_name(PyThreadState *, PyFrameObject *, - PyObject *, PyObject *, PyObject *); -static PyObject * import_from(PyThreadState *, PyObject *, PyObject *); -static int import_all_from(PyThreadState *, PyObject *, PyObject *); -static void format_exc_check_arg(PyThreadState *, PyObject *, const char *, PyObject *); -static void format_exc_unbound(PyThreadState *tstate, PyCodeObject *co, int oparg); -static PyObject * unicode_concatenate(PyThreadState *, PyObject *, PyObject *, - PyFrameObject *, const _Py_CODEUNIT *); -static PyObject * special_lookup(PyThreadState *, PyObject *, _Py_Identifier *); -static int check_args_iterable(PyThreadState *, PyObject *func, PyObject *vararg); -static void format_kwargs_error(PyThreadState *, PyObject *func, PyObject *kwargs); -static void format_awaitable_error(PyThreadState *, PyTypeObject *, int, int); - -#define NAME_ERROR_MSG \ - "name '%.200s' is not defined" -#define UNBOUNDLOCAL_ERROR_MSG \ - "local variable '%.200s' referenced before assignment" -#define UNBOUNDFREE_ERROR_MSG \ - "free variable '%.200s' referenced before assignment" \ - " in enclosing scope" - -/* Dynamic execution profile */ -#ifdef DYNAMIC_EXECUTION_PROFILE -#ifdef DXPAIRS -static long dxpairs[257][256]; -#define dxp dxpairs[256] -#else -static long dxp[256]; -#endif -#endif - -/* per opcode cache */ -static int opcache_min_runs = 1024; /* create opcache when code executed this many times */ -#define OPCODE_CACHE_MAX_TRIES 20 -#define OPCACHE_STATS 0 /* Enable stats */ - -// This function allows to deactivate the opcode cache. As different cache mechanisms may hold -// references, this can mess with the reference leak detector functionality so the cache needs -// to be deactivated in such scenarios to avoid false positives. See bpo-3714 for more information. -void -_PyEval_DeactivateOpCache(void) -{ - opcache_min_runs = 0; -} - -#if OPCACHE_STATS -static size_t opcache_code_objects = 0; -static size_t opcache_code_objects_extra_mem = 0; - -static size_t opcache_global_opts = 0; -static size_t opcache_global_hits = 0; -static size_t opcache_global_misses = 0; - -static size_t opcache_attr_opts = 0; -static size_t opcache_attr_hits = 0; -static size_t opcache_attr_misses = 0; -static size_t opcache_attr_deopts = 0; -static size_t opcache_attr_total = 0; -#endif - - -#ifndef NDEBUG -/* Ensure that tstate is valid: sanity check for PyEval_AcquireThread() and - PyEval_RestoreThread(). Detect if tstate memory was freed. It can happen - when a thread continues to run after Python finalization, especially - daemon threads. */ -static int -is_tstate_valid(PyThreadState *tstate) -{ - assert(!_PyMem_IsPtrFreed(tstate)); - assert(!_PyMem_IsPtrFreed(tstate->interp)); - return 1; -} -#endif - - -/* This can set eval_breaker to 0 even though gil_drop_request became - 1. We believe this is all right because the eval loop will release - the GIL eventually anyway. */ -static inline void -COMPUTE_EVAL_BREAKER(PyInterpreterState *interp, - struct _ceval_runtime_state *ceval, - struct _ceval_state *ceval2) -{ - _Py_atomic_store_relaxed(&ceval2->eval_breaker, - _Py_atomic_load_relaxed(&ceval2->gil_drop_request) - | (_Py_atomic_load_relaxed(&ceval->signals_pending) - && _Py_ThreadCanHandleSignals(interp)) - | (_Py_atomic_load_relaxed(&ceval2->pending.calls_to_do) - && _Py_ThreadCanHandlePendingCalls()) - | ceval2->pending.async_exc); -} - - -static inline void -SET_GIL_DROP_REQUEST(PyInterpreterState *interp) -{ - struct _ceval_state *ceval2 = &interp->ceval; - _Py_atomic_store_relaxed(&ceval2->gil_drop_request, 1); - _Py_atomic_store_relaxed(&ceval2->eval_breaker, 1); -} - - -static inline void -RESET_GIL_DROP_REQUEST(PyInterpreterState *interp) -{ - struct _ceval_runtime_state *ceval = &interp->runtime->ceval; - struct _ceval_state *ceval2 = &interp->ceval; - _Py_atomic_store_relaxed(&ceval2->gil_drop_request, 0); - COMPUTE_EVAL_BREAKER(interp, ceval, ceval2); -} - - -static inline void -SIGNAL_PENDING_CALLS(PyInterpreterState *interp) -{ - struct _ceval_runtime_state *ceval = &interp->runtime->ceval; - struct _ceval_state *ceval2 = &interp->ceval; - _Py_atomic_store_relaxed(&ceval2->pending.calls_to_do, 1); - COMPUTE_EVAL_BREAKER(interp, ceval, ceval2); -} - - -static inline void -UNSIGNAL_PENDING_CALLS(PyInterpreterState *interp) -{ - struct _ceval_runtime_state *ceval = &interp->runtime->ceval; - struct _ceval_state *ceval2 = &interp->ceval; - _Py_atomic_store_relaxed(&ceval2->pending.calls_to_do, 0); - COMPUTE_EVAL_BREAKER(interp, ceval, ceval2); -} - - -static inline void -SIGNAL_PENDING_SIGNALS(PyInterpreterState *interp, int force) -{ - struct _ceval_runtime_state *ceval = &interp->runtime->ceval; - struct _ceval_state *ceval2 = &interp->ceval; - _Py_atomic_store_relaxed(&ceval->signals_pending, 1); - if (force) { - _Py_atomic_store_relaxed(&ceval2->eval_breaker, 1); - } - else { - /* eval_breaker is not set to 1 if thread_can_handle_signals() is false */ - COMPUTE_EVAL_BREAKER(interp, ceval, ceval2); - } -} - - -static inline void -UNSIGNAL_PENDING_SIGNALS(PyInterpreterState *interp) -{ - struct _ceval_runtime_state *ceval = &interp->runtime->ceval; - struct _ceval_state *ceval2 = &interp->ceval; - _Py_atomic_store_relaxed(&ceval->signals_pending, 0); - COMPUTE_EVAL_BREAKER(interp, ceval, ceval2); -} - - -static inline void -SIGNAL_ASYNC_EXC(PyInterpreterState *interp) -{ - struct _ceval_state *ceval2 = &interp->ceval; - ceval2->pending.async_exc = 1; - _Py_atomic_store_relaxed(&ceval2->eval_breaker, 1); -} - - -static inline void -UNSIGNAL_ASYNC_EXC(PyInterpreterState *interp) -{ - struct _ceval_runtime_state *ceval = &interp->runtime->ceval; - struct _ceval_state *ceval2 = &interp->ceval; - ceval2->pending.async_exc = 0; - COMPUTE_EVAL_BREAKER(interp, ceval, ceval2); -} - - -#ifdef HAVE_ERRNO_H -#include <errno.h> -#endif -#include "ceval_gil.h" - -void _Py_NO_RETURN -_Py_FatalError_TstateNULL(const char *func) -{ - _Py_FatalErrorFunc(func, - "the function must be called with the GIL held, " - "but the GIL is released " - "(the current Python thread state is NULL)"); -} - -#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS -int -_PyEval_ThreadsInitialized(PyInterpreterState *interp) -{ - return gil_created(&interp->ceval.gil); -} - -int -PyEval_ThreadsInitialized(void) -{ - // Fatal error if there is no current interpreter - PyInterpreterState *interp = PyInterpreterState_Get(); - return _PyEval_ThreadsInitialized(interp); -} -#else -int -_PyEval_ThreadsInitialized(_PyRuntimeState *runtime) -{ - return gil_created(&runtime->ceval.gil); -} - -int -PyEval_ThreadsInitialized(void) -{ - _PyRuntimeState *runtime = &_PyRuntime; - return _PyEval_ThreadsInitialized(runtime); -} -#endif - -PyStatus -_PyEval_InitGIL(PyThreadState *tstate) -{ -#ifndef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS - if (!_Py_IsMainInterpreter(tstate->interp)) { - /* Currently, the GIL is shared by all interpreters, - and only the main interpreter is responsible to create - and destroy it. */ - return _PyStatus_OK(); - } -#endif - -#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS - struct _gil_runtime_state *gil = &tstate->interp->ceval.gil; -#else - struct _gil_runtime_state *gil = &tstate->interp->runtime->ceval.gil; -#endif - assert(!gil_created(gil)); - - PyThread_init_thread(); - create_gil(gil); - - take_gil(tstate); - - assert(gil_created(gil)); - return _PyStatus_OK(); -} - -void -_PyEval_FiniGIL(PyInterpreterState *interp) -{ -#ifndef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS - if (!_Py_IsMainInterpreter(interp)) { - /* Currently, the GIL is shared by all interpreters, - and only the main interpreter is responsible to create - and destroy it. */ - return; - } -#endif - -#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS - struct _gil_runtime_state *gil = &interp->ceval.gil; -#else - struct _gil_runtime_state *gil = &interp->runtime->ceval.gil; -#endif - if (!gil_created(gil)) { - /* First Py_InitializeFromConfig() call: the GIL doesn't exist - yet: do nothing. */ - return; - } - - destroy_gil(gil); - assert(!gil_created(gil)); -} - -void -PyEval_InitThreads(void) -{ - /* Do nothing: kept for backward compatibility */ -} - -void -_PyEval_Fini(void) -{ -#if OPCACHE_STATS - fprintf(stderr, "-- Opcode cache number of objects = %zd\n", - opcache_code_objects); - - fprintf(stderr, "-- Opcode cache total extra mem = %zd\n", - opcache_code_objects_extra_mem); - - fprintf(stderr, "\n"); - - fprintf(stderr, "-- Opcode cache LOAD_GLOBAL hits = %zd (%d%%)\n", - opcache_global_hits, - (int) (100.0 * opcache_global_hits / - (opcache_global_hits + opcache_global_misses))); - - fprintf(stderr, "-- Opcode cache LOAD_GLOBAL misses = %zd (%d%%)\n", - opcache_global_misses, - (int) (100.0 * opcache_global_misses / - (opcache_global_hits + opcache_global_misses))); - - fprintf(stderr, "-- Opcode cache LOAD_GLOBAL opts = %zd\n", - opcache_global_opts); - - fprintf(stderr, "\n"); - - fprintf(stderr, "-- Opcode cache LOAD_ATTR hits = %zd (%d%%)\n", - opcache_attr_hits, - (int) (100.0 * opcache_attr_hits / - opcache_attr_total)); - - fprintf(stderr, "-- Opcode cache LOAD_ATTR misses = %zd (%d%%)\n", - opcache_attr_misses, - (int) (100.0 * opcache_attr_misses / - opcache_attr_total)); - - fprintf(stderr, "-- Opcode cache LOAD_ATTR opts = %zd\n", - opcache_attr_opts); - - fprintf(stderr, "-- Opcode cache LOAD_ATTR deopts = %zd\n", - opcache_attr_deopts); - - fprintf(stderr, "-- Opcode cache LOAD_ATTR total = %zd\n", - opcache_attr_total); -#endif -} - -void -PyEval_AcquireLock(void) -{ - _PyRuntimeState *runtime = &_PyRuntime; - PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); - _Py_EnsureTstateNotNULL(tstate); - - take_gil(tstate); -} - -void -PyEval_ReleaseLock(void) -{ - _PyRuntimeState *runtime = &_PyRuntime; - PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); - /* This function must succeed when the current thread state is NULL. - We therefore avoid PyThreadState_Get() which dumps a fatal error - in debug mode. */ - struct _ceval_runtime_state *ceval = &runtime->ceval; - struct _ceval_state *ceval2 = &tstate->interp->ceval; - drop_gil(ceval, ceval2, tstate); -} - -void -_PyEval_ReleaseLock(PyThreadState *tstate) -{ - struct _ceval_runtime_state *ceval = &tstate->interp->runtime->ceval; - struct _ceval_state *ceval2 = &tstate->interp->ceval; - drop_gil(ceval, ceval2, tstate); -} - -void -PyEval_AcquireThread(PyThreadState *tstate) -{ - _Py_EnsureTstateNotNULL(tstate); - - take_gil(tstate); - - struct _gilstate_runtime_state *gilstate = &tstate->interp->runtime->gilstate; -#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS - (void)_PyThreadState_Swap(gilstate, tstate); -#else - if (_PyThreadState_Swap(gilstate, tstate) != NULL) { - Py_FatalError("non-NULL old thread state"); - } -#endif -} - -void -PyEval_ReleaseThread(PyThreadState *tstate) -{ - assert(is_tstate_valid(tstate)); - - _PyRuntimeState *runtime = tstate->interp->runtime; - PyThreadState *new_tstate = _PyThreadState_Swap(&runtime->gilstate, NULL); - if (new_tstate != tstate) { - Py_FatalError("wrong thread state"); - } - struct _ceval_runtime_state *ceval = &runtime->ceval; - struct _ceval_state *ceval2 = &tstate->interp->ceval; - drop_gil(ceval, ceval2, tstate); -} - -#ifdef HAVE_FORK -/* This function is called from PyOS_AfterFork_Child to destroy all threads - which are not running in the child process, and clear internal locks - which might be held by those threads. */ -PyStatus -_PyEval_ReInitThreads(PyThreadState *tstate) -{ - _PyRuntimeState *runtime = tstate->interp->runtime; - -#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS - struct _gil_runtime_state *gil = &tstate->interp->ceval.gil; -#else - struct _gil_runtime_state *gil = &runtime->ceval.gil; -#endif - if (!gil_created(gil)) { - return _PyStatus_OK(); - } - recreate_gil(gil); - - take_gil(tstate); - - struct _pending_calls *pending = &tstate->interp->ceval.pending; - if (_PyThread_at_fork_reinit(&pending->lock) < 0) { - return _PyStatus_ERR("Can't reinitialize pending calls lock"); - } - - /* Destroy all threads except the current one */ - _PyThreadState_DeleteExcept(runtime, tstate); - return _PyStatus_OK(); -} -#endif - -/* This function is used to signal that async exceptions are waiting to be - raised. */ - -void -_PyEval_SignalAsyncExc(PyInterpreterState *interp) -{ - SIGNAL_ASYNC_EXC(interp); -} - -PyThreadState * -PyEval_SaveThread(void) -{ - _PyRuntimeState *runtime = &_PyRuntime; -#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS - PyThreadState *old_tstate = _PyThreadState_GET(); - PyThreadState *tstate = _PyThreadState_Swap(&runtime->gilstate, old_tstate); -#else - PyThreadState *tstate = _PyThreadState_Swap(&runtime->gilstate, NULL); -#endif - _Py_EnsureTstateNotNULL(tstate); - - struct _ceval_runtime_state *ceval = &runtime->ceval; - struct _ceval_state *ceval2 = &tstate->interp->ceval; -#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS - assert(gil_created(&ceval2->gil)); -#else - assert(gil_created(&ceval->gil)); -#endif - drop_gil(ceval, ceval2, tstate); - return tstate; -} - -void -PyEval_RestoreThread(PyThreadState *tstate) -{ - _Py_EnsureTstateNotNULL(tstate); - - take_gil(tstate); - - struct _gilstate_runtime_state *gilstate = &tstate->interp->runtime->gilstate; - _PyThreadState_Swap(gilstate, tstate); -} - - -/* Mechanism whereby asynchronously executing callbacks (e.g. UNIX - signal handlers or Mac I/O completion routines) can schedule calls - to a function to be called synchronously. - The synchronous function is called with one void* argument. - It should return 0 for success or -1 for failure -- failure should - be accompanied by an exception. - - If registry succeeds, the registry function returns 0; if it fails - (e.g. due to too many pending calls) it returns -1 (without setting - an exception condition). - - Note that because registry may occur from within signal handlers, - or other asynchronous events, calling malloc() is unsafe! - - Any thread can schedule pending calls, but only the main thread - will execute them. - There is no facility to schedule calls to a particular thread, but - that should be easy to change, should that ever be required. In - that case, the static variables here should go into the python - threadstate. -*/ - -void -_PyEval_SignalReceived(PyInterpreterState *interp) -{ -#ifdef MS_WINDOWS - // bpo-42296: On Windows, _PyEval_SignalReceived() is called from a signal - // handler which can run in a thread different than the Python thread, in - // which case _Py_ThreadCanHandleSignals() is wrong. Ignore - // _Py_ThreadCanHandleSignals() and always set eval_breaker to 1. - // - // The next eval_frame_handle_pending() call will call - // _Py_ThreadCanHandleSignals() to recompute eval_breaker. - int force = 1; -#else - int force = 0; -#endif - /* bpo-30703: Function called when the C signal handler of Python gets a - signal. We cannot queue a callback using _PyEval_AddPendingCall() since - that function is not async-signal-safe. */ - SIGNAL_PENDING_SIGNALS(interp, force); -} - -/* Push one item onto the queue while holding the lock. */ -static int -_push_pending_call(struct _pending_calls *pending, - int (*func)(void *), void *arg) -{ - int i = pending->last; - int j = (i + 1) % NPENDINGCALLS; - if (j == pending->first) { - return -1; /* Queue full */ - } - pending->calls[i].func = func; - pending->calls[i].arg = arg; - pending->last = j; - return 0; -} - -/* Pop one item off the queue while holding the lock. */ -static void -_pop_pending_call(struct _pending_calls *pending, - int (**func)(void *), void **arg) -{ - int i = pending->first; - if (i == pending->last) { - return; /* Queue empty */ - } - - *func = pending->calls[i].func; - *arg = pending->calls[i].arg; - pending->first = (i + 1) % NPENDINGCALLS; -} - -/* This implementation is thread-safe. It allows - scheduling to be made from any thread, and even from an executing - callback. - */ - -int -_PyEval_AddPendingCall(PyInterpreterState *interp, - int (*func)(void *), void *arg) -{ - struct _pending_calls *pending = &interp->ceval.pending; - - /* Ensure that _PyEval_InitPendingCalls() was called - and that _PyEval_FiniPendingCalls() is not called yet. */ - assert(pending->lock != NULL); - - PyThread_acquire_lock(pending->lock, WAIT_LOCK); - int result = _push_pending_call(pending, func, arg); - PyThread_release_lock(pending->lock); - - /* signal main loop */ - SIGNAL_PENDING_CALLS(interp); - return result; -} - -int -Py_AddPendingCall(int (*func)(void *), void *arg) -{ - /* Best-effort to support subinterpreters and calls with the GIL released. - - First attempt _PyThreadState_GET() since it supports subinterpreters. - - If the GIL is released, _PyThreadState_GET() returns NULL . In this - case, use PyGILState_GetThisThreadState() which works even if the GIL - is released. - - Sadly, PyGILState_GetThisThreadState() doesn't support subinterpreters: - see bpo-10915 and bpo-15751. - - Py_AddPendingCall() doesn't require the caller to hold the GIL. */ - PyThreadState *tstate = _PyThreadState_GET(); - if (tstate == NULL) { - tstate = PyGILState_GetThisThreadState(); - } - - PyInterpreterState *interp; - if (tstate != NULL) { - interp = tstate->interp; - } - else { - /* Last resort: use the main interpreter */ - interp = _PyRuntime.interpreters.main; - } - return _PyEval_AddPendingCall(interp, func, arg); -} - -static int -handle_signals(PyThreadState *tstate) -{ - assert(is_tstate_valid(tstate)); - if (!_Py_ThreadCanHandleSignals(tstate->interp)) { - return 0; - } - - UNSIGNAL_PENDING_SIGNALS(tstate->interp); - if (_PyErr_CheckSignalsTstate(tstate) < 0) { - /* On failure, re-schedule a call to handle_signals(). */ - SIGNAL_PENDING_SIGNALS(tstate->interp, 0); - return -1; - } - return 0; -} - -static int -make_pending_calls(PyInterpreterState *interp) -{ - /* only execute pending calls on main thread */ - if (!_Py_ThreadCanHandlePendingCalls()) { - return 0; - } - - /* don't perform recursive pending calls */ - static int busy = 0; - if (busy) { - return 0; - } - busy = 1; - - /* unsignal before starting to call callbacks, so that any callback - added in-between re-signals */ - UNSIGNAL_PENDING_CALLS(interp); - int res = 0; - - /* perform a bounded number of calls, in case of recursion */ - struct _pending_calls *pending = &interp->ceval.pending; - for (int i=0; i<NPENDINGCALLS; i++) { - int (*func)(void *) = NULL; - void *arg = NULL; - - /* pop one item off the queue while holding the lock */ - PyThread_acquire_lock(pending->lock, WAIT_LOCK); - _pop_pending_call(pending, &func, &arg); - PyThread_release_lock(pending->lock); - - /* having released the lock, perform the callback */ - if (func == NULL) { - break; - } - res = func(arg); - if (res) { - goto error; - } - } - - busy = 0; - return res; - -error: - busy = 0; - SIGNAL_PENDING_CALLS(interp); - return res; -} - -void -_Py_FinishPendingCalls(PyThreadState *tstate) -{ - assert(PyGILState_Check()); - assert(is_tstate_valid(tstate)); - - struct _pending_calls *pending = &tstate->interp->ceval.pending; - - if (!_Py_atomic_load_relaxed(&(pending->calls_to_do))) { - return; - } - - if (make_pending_calls(tstate->interp) < 0) { - PyObject *exc, *val, *tb; - _PyErr_Fetch(tstate, &exc, &val, &tb); - PyErr_BadInternalCall(); - _PyErr_ChainExceptions(exc, val, tb); - _PyErr_Print(tstate); - } -} - -/* Py_MakePendingCalls() is a simple wrapper for the sake - of backward-compatibility. */ -int -Py_MakePendingCalls(void) -{ - assert(PyGILState_Check()); - - PyThreadState *tstate = _PyThreadState_GET(); - assert(is_tstate_valid(tstate)); - - /* Python signal handler doesn't really queue a callback: it only signals - that a signal was received, see _PyEval_SignalReceived(). */ - int res = handle_signals(tstate); - if (res != 0) { - return res; - } - - res = make_pending_calls(tstate->interp); - if (res != 0) { - return res; - } - - return 0; -} - -/* The interpreter's recursion limit */ - -#ifndef Py_DEFAULT_RECURSION_LIMIT -# define Py_DEFAULT_RECURSION_LIMIT 1000 -#endif - -void -_PyEval_InitRuntimeState(struct _ceval_runtime_state *ceval) -{ -#ifndef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS - _gil_initialize(&ceval->gil); -#endif -} - -int -_PyEval_InitState(struct _ceval_state *ceval) -{ - ceval->recursion_limit = Py_DEFAULT_RECURSION_LIMIT; - - struct _pending_calls *pending = &ceval->pending; - assert(pending->lock == NULL); - - pending->lock = PyThread_allocate_lock(); - if (pending->lock == NULL) { - return -1; - } - -#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS - _gil_initialize(&ceval->gil); -#endif - - return 0; -} - -void -_PyEval_FiniState(struct _ceval_state *ceval) -{ - struct _pending_calls *pending = &ceval->pending; - if (pending->lock != NULL) { - PyThread_free_lock(pending->lock); - pending->lock = NULL; - } -} - -int -Py_GetRecursionLimit(void) -{ - PyInterpreterState *interp = _PyInterpreterState_GET(); - return interp->ceval.recursion_limit; -} - -void -Py_SetRecursionLimit(int new_limit) -{ - PyThreadState *tstate = _PyThreadState_GET(); - tstate->interp->ceval.recursion_limit = new_limit; -} - -/* The function _Py_EnterRecursiveCall() only calls _Py_CheckRecursiveCall() - if the recursion_depth reaches recursion_limit. - If USE_STACKCHECK, the macro decrements recursion_limit - to guarantee that _Py_CheckRecursiveCall() is regularly called. - Without USE_STACKCHECK, there is no need for this. */ -int -_Py_CheckRecursiveCall(PyThreadState *tstate, const char *where) -{ - int recursion_limit = tstate->interp->ceval.recursion_limit; - -#ifdef USE_STACKCHECK - tstate->stackcheck_counter = 0; - if (PyOS_CheckStack()) { - --tstate->recursion_depth; - _PyErr_SetString(tstate, PyExc_MemoryError, "Stack overflow"); - return -1; - } -#endif - if (tstate->recursion_headroom) { - if (tstate->recursion_depth > recursion_limit + 50) { - /* Overflowing while handling an overflow. Give up. */ - Py_FatalError("Cannot recover from stack overflow."); - } - } - else { - if (tstate->recursion_depth > recursion_limit) { - tstate->recursion_headroom++; - _PyErr_Format(tstate, PyExc_RecursionError, - "maximum recursion depth exceeded%s", - where); - tstate->recursion_headroom--; - --tstate->recursion_depth; - return -1; - } - } - return 0; -} - - -// PEP 634: Structural Pattern Matching - - -// Return a tuple of values corresponding to keys, with error checks for -// duplicate/missing keys. -static PyObject* -match_keys(PyThreadState *tstate, PyObject *map, PyObject *keys) -{ - assert(PyTuple_CheckExact(keys)); - Py_ssize_t nkeys = PyTuple_GET_SIZE(keys); - if (!nkeys) { - // No keys means no items. - return PyTuple_New(0); - } - PyObject *seen = NULL; - PyObject *dummy = NULL; - PyObject *values = NULL; - // We use the two argument form of map.get(key, default) for two reasons: - // - Atomically check for a key and get its value without error handling. - // - Don't cause key creation or resizing in dict subclasses like - // collections.defaultdict that define __missing__ (or similar). - _Py_IDENTIFIER(get); - PyObject *get = _PyObject_GetAttrId(map, &PyId_get); - if (get == NULL) { - goto fail; - } - seen = PySet_New(NULL); - if (seen == NULL) { - goto fail; - } - // dummy = object() - dummy = _PyObject_CallNoArg((PyObject *)&PyBaseObject_Type); - if (dummy == NULL) { - goto fail; - } - values = PyList_New(0); - if (values == NULL) { - goto fail; - } - for (Py_ssize_t i = 0; i < nkeys; i++) { - PyObject *key = PyTuple_GET_ITEM(keys, i); - if (PySet_Contains(seen, key) || PySet_Add(seen, key)) { - if (!_PyErr_Occurred(tstate)) { - // Seen it before! - _PyErr_Format(tstate, PyExc_ValueError, - "mapping pattern checks duplicate key (%R)", key); - } - goto fail; - } - PyObject *value = PyObject_CallFunctionObjArgs(get, key, dummy, NULL); - if (value == NULL) { - goto fail; - } - if (value == dummy) { - // key not in map! - Py_DECREF(value); - Py_DECREF(values); - // Return None: - Py_INCREF(Py_None); - values = Py_None; - goto done; - } - PyList_Append(values, value); - Py_DECREF(value); - } - Py_SETREF(values, PyList_AsTuple(values)); - // Success: -done: - Py_DECREF(get); - Py_DECREF(seen); - Py_DECREF(dummy); - return values; -fail: - Py_XDECREF(get); - Py_XDECREF(seen); - Py_XDECREF(dummy); - Py_XDECREF(values); - return NULL; -} - -// Extract a named attribute from the subject, with additional bookkeeping to -// raise TypeErrors for repeated lookups. On failure, return NULL (with no -// error set). Use _PyErr_Occurred(tstate) to disambiguate. -static PyObject* -match_class_attr(PyThreadState *tstate, PyObject *subject, PyObject *type, - PyObject *name, PyObject *seen) -{ - assert(PyUnicode_CheckExact(name)); - assert(PySet_CheckExact(seen)); - if (PySet_Contains(seen, name) || PySet_Add(seen, name)) { - if (!_PyErr_Occurred(tstate)) { - // Seen it before! - _PyErr_Format(tstate, PyExc_TypeError, - "%s() got multiple sub-patterns for attribute %R", - ((PyTypeObject*)type)->tp_name, name); - } - return NULL; - } - PyObject *attr = PyObject_GetAttr(subject, name); - if (attr == NULL && _PyErr_ExceptionMatches(tstate, PyExc_AttributeError)) { - _PyErr_Clear(tstate); - } - return attr; -} - -// On success (match), return a tuple of extracted attributes. On failure (no -// match), return NULL. Use _PyErr_Occurred(tstate) to disambiguate. -static PyObject* -match_class(PyThreadState *tstate, PyObject *subject, PyObject *type, - Py_ssize_t nargs, PyObject *kwargs) -{ - if (!PyType_Check(type)) { - const char *e = "called match pattern must be a type"; - _PyErr_Format(tstate, PyExc_TypeError, e); - return NULL; - } - assert(PyTuple_CheckExact(kwargs)); - // First, an isinstance check: - if (PyObject_IsInstance(subject, type) <= 0) { - return NULL; - } - // So far so good: - PyObject *seen = PySet_New(NULL); - if (seen == NULL) { - return NULL; - } - PyObject *attrs = PyList_New(0); - if (attrs == NULL) { - Py_DECREF(seen); - return NULL; - } - // NOTE: From this point on, goto fail on failure: - PyObject *match_args = NULL; - // First, the positional subpatterns: - if (nargs) { - int match_self = 0; - match_args = PyObject_GetAttrString(type, "__match_args__"); - if (match_args) { - if (!PyTuple_CheckExact(match_args)) { - const char *e = "%s.__match_args__ must be a tuple (got %s)"; - _PyErr_Format(tstate, PyExc_TypeError, e, - ((PyTypeObject *)type)->tp_name, - Py_TYPE(match_args)->tp_name); - goto fail; - } - } - else if (_PyErr_ExceptionMatches(tstate, PyExc_AttributeError)) { - _PyErr_Clear(tstate); - // _Py_TPFLAGS_MATCH_SELF is only acknowledged if the type does not - // define __match_args__. This is natural behavior for subclasses: - // it's as if __match_args__ is some "magic" value that is lost as - // soon as they redefine it. - match_args = PyTuple_New(0); - match_self = PyType_HasFeature((PyTypeObject*)type, - _Py_TPFLAGS_MATCH_SELF); - } - else { - goto fail; - } - assert(PyTuple_CheckExact(match_args)); - Py_ssize_t allowed = match_self ? 1 : PyTuple_GET_SIZE(match_args); - if (allowed < nargs) { - const char *plural = (allowed == 1) ? "" : "s"; - _PyErr_Format(tstate, PyExc_TypeError, - "%s() accepts %d positional sub-pattern%s (%d given)", - ((PyTypeObject*)type)->tp_name, - allowed, plural, nargs); - goto fail; - } - if (match_self) { - // Easy. Copy the subject itself, and move on to kwargs. - PyList_Append(attrs, subject); - } - else { - for (Py_ssize_t i = 0; i < nargs; i++) { - PyObject *name = PyTuple_GET_ITEM(match_args, i); - if (!PyUnicode_CheckExact(name)) { - _PyErr_Format(tstate, PyExc_TypeError, - "__match_args__ elements must be strings " - "(got %s)", Py_TYPE(name)->tp_name); - goto fail; - } - PyObject *attr = match_class_attr(tstate, subject, type, name, - seen); - if (attr == NULL) { - goto fail; - } - PyList_Append(attrs, attr); - Py_DECREF(attr); - } - } - Py_CLEAR(match_args); - } - // Finally, the keyword subpatterns: - for (Py_ssize_t i = 0; i < PyTuple_GET_SIZE(kwargs); i++) { - PyObject *name = PyTuple_GET_ITEM(kwargs, i); - PyObject *attr = match_class_attr(tstate, subject, type, name, seen); - if (attr == NULL) { - goto fail; - } - PyList_Append(attrs, attr); - Py_DECREF(attr); - } - Py_SETREF(attrs, PyList_AsTuple(attrs)); - Py_DECREF(seen); - return attrs; -fail: - // We really don't care whether an error was raised or not... that's our - // caller's problem. All we know is that the match failed. - Py_XDECREF(match_args); - Py_DECREF(seen); - Py_DECREF(attrs); - return NULL; -} - - -static int do_raise(PyThreadState *tstate, PyObject *exc, PyObject *cause); -static int unpack_iterable(PyThreadState *, PyObject *, int, int, PyObject **); - - -PyObject * -PyEval_EvalCode(PyObject *co, PyObject *globals, PyObject *locals) -{ - PyThreadState *tstate = PyThreadState_GET(); - if (locals == NULL) { - locals = globals; - } - PyObject *builtins = _PyEval_BuiltinsFromGlobals(tstate, globals); // borrowed ref - if (builtins == NULL) { - return NULL; - } - PyFrameConstructor desc = { - .fc_globals = globals, - .fc_builtins = builtins, - .fc_name = ((PyCodeObject *)co)->co_name, - .fc_qualname = ((PyCodeObject *)co)->co_name, - .fc_code = co, - .fc_defaults = NULL, - .fc_kwdefaults = NULL, - .fc_closure = NULL - }; - return _PyEval_Vector(tstate, &desc, locals, NULL, 0, NULL); -} - - -/* Interpreter main loop */ - -PyObject * -PyEval_EvalFrame(PyFrameObject *f) -{ - /* Function kept for backward compatibility */ - PyThreadState *tstate = _PyThreadState_GET(); - return _PyEval_EvalFrame(tstate, f, 0); -} - -PyObject * -PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) -{ - PyThreadState *tstate = _PyThreadState_GET(); - return _PyEval_EvalFrame(tstate, f, throwflag); -} - - -/* Handle signals, pending calls, GIL drop request - and asynchronous exception */ -static int -eval_frame_handle_pending(PyThreadState *tstate) -{ - _PyRuntimeState * const runtime = &_PyRuntime; - struct _ceval_runtime_state *ceval = &runtime->ceval; - - /* Pending signals */ - if (_Py_atomic_load_relaxed(&ceval->signals_pending)) { - if (handle_signals(tstate) != 0) { - return -1; - } - } - - /* Pending calls */ - struct _ceval_state *ceval2 = &tstate->interp->ceval; - if (_Py_atomic_load_relaxed(&ceval2->pending.calls_to_do)) { - if (make_pending_calls(tstate->interp) != 0) { - return -1; - } - } - - /* GIL drop request */ - if (_Py_atomic_load_relaxed(&ceval2->gil_drop_request)) { - /* Give another thread a chance */ - if (_PyThreadState_Swap(&runtime->gilstate, NULL) != tstate) { - Py_FatalError("tstate mix-up"); - } - drop_gil(ceval, ceval2, tstate); - - /* Other threads may run now */ - - take_gil(tstate); - -#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS - (void)_PyThreadState_Swap(&runtime->gilstate, tstate); -#else - if (_PyThreadState_Swap(&runtime->gilstate, tstate) != NULL) { - Py_FatalError("orphan tstate"); - } -#endif - } - - /* Check for asynchronous exception. */ - if (tstate->async_exc != NULL) { - PyObject *exc = tstate->async_exc; - tstate->async_exc = NULL; - UNSIGNAL_ASYNC_EXC(tstate->interp); - _PyErr_SetNone(tstate, exc); - Py_DECREF(exc); - return -1; - } - -#ifdef MS_WINDOWS - // bpo-42296: On Windows, _PyEval_SignalReceived() can be called in a - // different thread than the Python thread, in which case - // _Py_ThreadCanHandleSignals() is wrong. Recompute eval_breaker in the - // current Python thread with the correct _Py_ThreadCanHandleSignals() - // value. It prevents to interrupt the eval loop at every instruction if - // the current Python thread cannot handle signals (if - // _Py_ThreadCanHandleSignals() is false). - COMPUTE_EVAL_BREAKER(tstate->interp, ceval, ceval2); -#endif - - return 0; -} - - -/* Computed GOTOs, or - the-optimization-commonly-but-improperly-known-as-"threaded code" - using gcc's labels-as-values extension - (http://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html). - - The traditional bytecode evaluation loop uses a "switch" statement, which - decent compilers will optimize as a single indirect branch instruction - combined with a lookup table of jump addresses. However, since the - indirect jump instruction is shared by all opcodes, the CPU will have a - hard time making the right prediction for where to jump next (actually, - it will be always wrong except in the uncommon case of a sequence of - several identical opcodes). - - "Threaded code" in contrast, uses an explicit jump table and an explicit - indirect jump instruction at the end of each opcode. Since the jump - instruction is at a different address for each opcode, the CPU will make a - separate prediction for each of these instructions, which is equivalent to - predicting the second opcode of each opcode pair. These predictions have - a much better chance to turn out valid, especially in small bytecode loops. - - A mispredicted branch on a modern CPU flushes the whole pipeline and - can cost several CPU cycles (depending on the pipeline depth), - and potentially many more instructions (depending on the pipeline width). - A correctly predicted branch, however, is nearly free. - - At the time of this writing, the "threaded code" version is up to 15-20% - faster than the normal "switch" version, depending on the compiler and the - CPU architecture. - - We disable the optimization if DYNAMIC_EXECUTION_PROFILE is defined, - because it would render the measurements invalid. - - - NOTE: care must be taken that the compiler doesn't try to "optimize" the - indirect jumps by sharing them between all opcodes. Such optimizations - can be disabled on gcc by using the -fno-gcse flag (or possibly - -fno-crossjumping). -*/ - -/* Use macros rather than inline functions, to make it as clear as possible - * to the C compiler that the tracing check is a simple test then branch. - * We want to be sure that the compiler knows this before it generates - * the CFG. - */ -#ifdef LLTRACE -#define OR_LLTRACE || lltrace -#else -#define OR_LLTRACE -#endif - -#ifdef WITH_DTRACE -#define OR_DTRACE_LINE || PyDTrace_LINE_ENABLED() -#else -#define OR_DTRACE_LINE -#endif - -#ifdef DYNAMIC_EXECUTION_PROFILE -#undef USE_COMPUTED_GOTOS -#define USE_COMPUTED_GOTOS 0 -#endif - -#ifdef HAVE_COMPUTED_GOTOS - #ifndef USE_COMPUTED_GOTOS - #define USE_COMPUTED_GOTOS 1 - #endif -#else - #if defined(USE_COMPUTED_GOTOS) && USE_COMPUTED_GOTOS - #error "Computed gotos are not supported on this compiler." - #endif - #undef USE_COMPUTED_GOTOS - #define USE_COMPUTED_GOTOS 0 -#endif - -#if USE_COMPUTED_GOTOS -#define TARGET(op) op: TARGET_##op -#define DISPATCH() \ - { \ - if (trace_info.cframe.use_tracing OR_DTRACE_LINE OR_LLTRACE) { \ - goto tracing_dispatch; \ - } \ - f->f_lasti = INSTR_OFFSET(); \ - NEXTOPARG(); \ - goto *opcode_targets[opcode]; \ - } -#else -#define TARGET(op) op -#define DISPATCH() goto predispatch; -#endif - - -#define CHECK_EVAL_BREAKER() \ - if (_Py_atomic_load_relaxed(eval_breaker)) { \ - continue; \ - } - - -/* Tuple access macros */ - -#ifndef Py_DEBUG -#define GETITEM(v, i) PyTuple_GET_ITEM((PyTupleObject *)(v), (i)) -#else -#define GETITEM(v, i) PyTuple_GetItem((v), (i)) -#endif - -/* Code access macros */ - -/* The integer overflow is checked by an assertion below. */ -#define INSTR_OFFSET() ((int)(next_instr - first_instr)) -#define NEXTOPARG() do { \ - _Py_CODEUNIT word = *next_instr; \ - opcode = _Py_OPCODE(word); \ - oparg = _Py_OPARG(word); \ - next_instr++; \ - } while (0) -#define JUMPTO(x) (next_instr = first_instr + (x)) -#define JUMPBY(x) (next_instr += (x)) - -/* OpCode prediction macros - Some opcodes tend to come in pairs thus making it possible to - predict the second code when the first is run. For example, - COMPARE_OP is often followed by POP_JUMP_IF_FALSE or POP_JUMP_IF_TRUE. - - Verifying the prediction costs a single high-speed test of a register - variable against a constant. If the pairing was good, then the - processor's own internal branch predication has a high likelihood of - success, resulting in a nearly zero-overhead transition to the - next opcode. A successful prediction saves a trip through the eval-loop - including its unpredictable switch-case branch. Combined with the - processor's internal branch prediction, a successful PREDICT has the - effect of making the two opcodes run as if they were a single new opcode - with the bodies combined. - - If collecting opcode statistics, your choices are to either keep the - predictions turned-on and interpret the results as if some opcodes - had been combined or turn-off predictions so that the opcode frequency - counter updates for both opcodes. - - Opcode prediction is disabled with threaded code, since the latter allows - the CPU to record separate branch prediction information for each - opcode. - -*/ - -#define PREDICT_ID(op) PRED_##op - -#if defined(DYNAMIC_EXECUTION_PROFILE) || USE_COMPUTED_GOTOS -#define PREDICT(op) if (0) goto PREDICT_ID(op) -#else -#define PREDICT(op) \ - do { \ - _Py_CODEUNIT word = *next_instr; \ - opcode = _Py_OPCODE(word); \ - if (opcode == op) { \ - oparg = _Py_OPARG(word); \ - next_instr++; \ - goto PREDICT_ID(op); \ - } \ - } while(0) -#endif -#define PREDICTED(op) PREDICT_ID(op): - - -/* Stack manipulation macros */ - -/* The stack can grow at most MAXINT deep, as co_nlocals and - co_stacksize are ints. */ -#define STACK_LEVEL() ((int)(stack_pointer - f->f_valuestack)) -#define EMPTY() (STACK_LEVEL() == 0) -#define TOP() (stack_pointer[-1]) -#define SECOND() (stack_pointer[-2]) -#define THIRD() (stack_pointer[-3]) -#define FOURTH() (stack_pointer[-4]) -#define PEEK(n) (stack_pointer[-(n)]) -#define SET_TOP(v) (stack_pointer[-1] = (v)) -#define SET_SECOND(v) (stack_pointer[-2] = (v)) -#define SET_THIRD(v) (stack_pointer[-3] = (v)) -#define SET_FOURTH(v) (stack_pointer[-4] = (v)) -#define BASIC_STACKADJ(n) (stack_pointer += n) -#define BASIC_PUSH(v) (*stack_pointer++ = (v)) -#define BASIC_POP() (*--stack_pointer) - -#ifdef LLTRACE -#define PUSH(v) { (void)(BASIC_PUSH(v), \ - lltrace && prtrace(tstate, TOP(), "push")); \ - assert(STACK_LEVEL() <= co->co_stacksize); } -#define POP() ((void)(lltrace && prtrace(tstate, TOP(), "pop")), \ - BASIC_POP()) -#define STACK_GROW(n) do { \ - assert(n >= 0); \ - (void)(BASIC_STACKADJ(n), \ - lltrace && prtrace(tstate, TOP(), "stackadj")); \ - assert(STACK_LEVEL() <= co->co_stacksize); \ - } while (0) -#define STACK_SHRINK(n) do { \ - assert(n >= 0); \ - (void)(lltrace && prtrace(tstate, TOP(), "stackadj")); \ - (void)(BASIC_STACKADJ(-n)); \ - assert(STACK_LEVEL() <= co->co_stacksize); \ - } while (0) -#define EXT_POP(STACK_POINTER) ((void)(lltrace && \ - prtrace(tstate, (STACK_POINTER)[-1], "ext_pop")), \ - *--(STACK_POINTER)) -#else -#define PUSH(v) BASIC_PUSH(v) -#define POP() BASIC_POP() -#define STACK_GROW(n) BASIC_STACKADJ(n) -#define STACK_SHRINK(n) BASIC_STACKADJ(-n) -#define EXT_POP(STACK_POINTER) (*--(STACK_POINTER)) -#endif - -/* Local variable macros */ - -#define GETLOCAL(i) (fastlocals[i]) - -/* The SETLOCAL() macro must not DECREF the local variable in-place and - then store the new value; it must copy the old value to a temporary - value, then store the new value, and then DECREF the temporary value. - This is because it is possible that during the DECREF the frame is - accessed by other code (e.g. a __del__ method or gc.collect()) and the - variable would be pointing to already-freed memory. */ -#define SETLOCAL(i, value) do { PyObject *tmp = GETLOCAL(i); \ - GETLOCAL(i) = value; \ - Py_XDECREF(tmp); } while (0) - - -#define UNWIND_BLOCK(b) \ - while (STACK_LEVEL() > (b)->b_level) { \ - PyObject *v = POP(); \ - Py_XDECREF(v); \ - } - -#define UNWIND_EXCEPT_HANDLER(b) \ - do { \ - PyObject *type, *value, *traceback; \ - _PyErr_StackItem *exc_info; \ - assert(STACK_LEVEL() >= (b)->b_level + 3); \ - while (STACK_LEVEL() > (b)->b_level + 3) { \ - value = POP(); \ - Py_XDECREF(value); \ - } \ - exc_info = tstate->exc_info; \ - type = exc_info->exc_type; \ - value = exc_info->exc_value; \ - traceback = exc_info->exc_traceback; \ - exc_info->exc_type = POP(); \ - exc_info->exc_value = POP(); \ - exc_info->exc_traceback = POP(); \ - Py_XDECREF(type); \ - Py_XDECREF(value); \ - Py_XDECREF(traceback); \ - } while(0) - - /* macros for opcode cache */ -#define OPCACHE_CHECK() \ - do { \ - co_opcache = NULL; \ - if (co->co_opcache != NULL) { \ - unsigned char co_opcache_offset = \ - co->co_opcache_map[next_instr - first_instr]; \ - if (co_opcache_offset > 0) { \ - assert(co_opcache_offset <= co->co_opcache_size); \ - co_opcache = &co->co_opcache[co_opcache_offset - 1]; \ - assert(co_opcache != NULL); \ - } \ - } \ - } while (0) - -#define OPCACHE_DEOPT() \ - do { \ - if (co_opcache != NULL) { \ - co_opcache->optimized = -1; \ - unsigned char co_opcache_offset = \ - co->co_opcache_map[next_instr - first_instr]; \ - assert(co_opcache_offset <= co->co_opcache_size); \ - co->co_opcache_map[co_opcache_offset] = 0; \ - co_opcache = NULL; \ - } \ - } while (0) - -#define OPCACHE_DEOPT_LOAD_ATTR() \ - do { \ - if (co_opcache != NULL) { \ - OPCACHE_STAT_ATTR_DEOPT(); \ - OPCACHE_DEOPT(); \ - } \ - } while (0) - -#define OPCACHE_MAYBE_DEOPT_LOAD_ATTR() \ - do { \ - if (co_opcache != NULL && --co_opcache->optimized <= 0) { \ - OPCACHE_DEOPT_LOAD_ATTR(); \ - } \ - } while (0) - -#if OPCACHE_STATS - -#define OPCACHE_STAT_GLOBAL_HIT() \ - do { \ - if (co->co_opcache != NULL) opcache_global_hits++; \ - } while (0) - -#define OPCACHE_STAT_GLOBAL_MISS() \ - do { \ - if (co->co_opcache != NULL) opcache_global_misses++; \ - } while (0) - -#define OPCACHE_STAT_GLOBAL_OPT() \ - do { \ - if (co->co_opcache != NULL) opcache_global_opts++; \ - } while (0) - -#define OPCACHE_STAT_ATTR_HIT() \ - do { \ - if (co->co_opcache != NULL) opcache_attr_hits++; \ - } while (0) - -#define OPCACHE_STAT_ATTR_MISS() \ - do { \ - if (co->co_opcache != NULL) opcache_attr_misses++; \ - } while (0) - -#define OPCACHE_STAT_ATTR_OPT() \ - do { \ - if (co->co_opcache!= NULL) opcache_attr_opts++; \ - } while (0) - -#define OPCACHE_STAT_ATTR_DEOPT() \ - do { \ - if (co->co_opcache != NULL) opcache_attr_deopts++; \ - } while (0) - -#define OPCACHE_STAT_ATTR_TOTAL() \ - do { \ - if (co->co_opcache != NULL) opcache_attr_total++; \ - } while (0) - -#else /* OPCACHE_STATS */ - -#define OPCACHE_STAT_GLOBAL_HIT() -#define OPCACHE_STAT_GLOBAL_MISS() -#define OPCACHE_STAT_GLOBAL_OPT() - -#define OPCACHE_STAT_ATTR_HIT() -#define OPCACHE_STAT_ATTR_MISS() -#define OPCACHE_STAT_ATTR_OPT() -#define OPCACHE_STAT_ATTR_DEOPT() -#define OPCACHE_STAT_ATTR_TOTAL() - -#endif - - -PyObject* _Py_HOT_FUNCTION -_PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag) -{ - _Py_EnsureTstateNotNULL(tstate); - -#if USE_COMPUTED_GOTOS -/* Import the static jump table */ -#include "opcode_targets.h" -#endif - -#ifdef DXPAIRS - int lastopcode = 0; -#endif - PyObject **stack_pointer; /* Next free slot in value stack */ - const _Py_CODEUNIT *next_instr; - int opcode; /* Current opcode */ - int oparg; /* Current opcode argument, if any */ - PyObject **fastlocals, **freevars; - PyObject *retval = NULL; /* Return value */ - _Py_atomic_int * const eval_breaker = &tstate->interp->ceval.eval_breaker; - PyCodeObject *co; - - const _Py_CODEUNIT *first_instr; - PyObject *names; - PyObject *consts; - _PyOpcache *co_opcache; - -#ifdef LLTRACE - _Py_IDENTIFIER(__ltrace__); -#endif - - if (_Py_EnterRecursiveCall(tstate, "")) { - return NULL; - } - - PyTraceInfo trace_info; - /* Mark trace_info as uninitialized */ - trace_info.code = NULL; - - /* WARNING: Because the CFrame lives on the C stack, - * but can be accessed from a heap allocated object (tstate) - * strict stack discipline must be maintained. - */ - CFrame *prev_cframe = tstate->cframe; - trace_info.cframe.use_tracing = prev_cframe->use_tracing; - trace_info.cframe.previous = prev_cframe; - tstate->cframe = &trace_info.cframe; - - /* push frame */ - tstate->frame = f; - co = f->f_code; - - if (trace_info.cframe.use_tracing) { - if (tstate->c_tracefunc != NULL) { - /* tstate->c_tracefunc, if defined, is a - function that will be called on *every* entry - to a code block. Its return value, if not - None, is a function that will be called at - the start of each executed line of code. - (Actually, the function must return itself - in order to continue tracing.) The trace - functions are called with three arguments: - a pointer to the current frame, a string - indicating why the function is called, and - an argument which depends on the situation. - The global trace function is also called - whenever an exception is detected. */ - if (call_trace_protected(tstate->c_tracefunc, - tstate->c_traceobj, - tstate, f, &trace_info, - PyTrace_CALL, Py_None)) { - /* Trace function raised an error */ - goto exit_eval_frame; - } - } - if (tstate->c_profilefunc != NULL) { - /* Similar for c_profilefunc, except it needn't - return itself and isn't called for "line" events */ - if (call_trace_protected(tstate->c_profilefunc, - tstate->c_profileobj, - tstate, f, &trace_info, - PyTrace_CALL, Py_None)) { - /* Profile function raised an error */ - goto exit_eval_frame; - } - } - } - - if (PyDTrace_FUNCTION_ENTRY_ENABLED()) - dtrace_function_entry(f); - - names = co->co_names; - consts = co->co_consts; - fastlocals = f->f_localsplus; - freevars = f->f_localsplus + co->co_nlocals; - assert(PyBytes_Check(co->co_code)); - assert(PyBytes_GET_SIZE(co->co_code) <= INT_MAX); - assert(PyBytes_GET_SIZE(co->co_code) % sizeof(_Py_CODEUNIT) == 0); - assert(_Py_IS_ALIGNED(PyBytes_AS_STRING(co->co_code), sizeof(_Py_CODEUNIT))); - first_instr = (_Py_CODEUNIT *) PyBytes_AS_STRING(co->co_code); - /* - f->f_lasti refers to the index of the last instruction, - unless it's -1 in which case next_instr should be first_instr. - - YIELD_FROM sets f_lasti to itself, in order to repeatedly yield - multiple values. - - When the PREDICT() macros are enabled, some opcode pairs follow in - direct succession without updating f->f_lasti. A successful - prediction effectively links the two codes together as if they - were a single new opcode; accordingly,f->f_lasti will point to - the first code in the pair (for instance, GET_ITER followed by - FOR_ITER is effectively a single opcode and f->f_lasti will point - to the beginning of the combined pair.) - */ - assert(f->f_lasti >= -1); - next_instr = first_instr + f->f_lasti + 1; - stack_pointer = f->f_valuestack + f->f_stackdepth; - /* Set f->f_stackdepth to -1. - * Update when returning or calling trace function. - Having f_stackdepth <= 0 ensures that invalid - values are not visible to the cycle GC. - We choose -1 rather than 0 to assist debugging. - */ - f->f_stackdepth = -1; - f->f_state = FRAME_EXECUTING; - - if (co->co_opcache_flag < opcache_min_runs) { - co->co_opcache_flag++; - if (co->co_opcache_flag == opcache_min_runs) { - if (_PyCode_InitOpcache(co) < 0) { - goto exit_eval_frame; - } -#if OPCACHE_STATS - opcache_code_objects_extra_mem += - PyBytes_Size(co->co_code) / sizeof(_Py_CODEUNIT) + - sizeof(_PyOpcache) * co->co_opcache_size; - opcache_code_objects++; -#endif - } - } - -#ifdef LLTRACE - { - int r = _PyDict_ContainsId(f->f_globals, &PyId___ltrace__); - if (r < 0) { - goto exit_eval_frame; - } - lltrace = r; - } -#endif - - if (throwflag) { /* support for generator.throw() */ - goto error; - } - -#ifdef Py_DEBUG - /* _PyEval_EvalFrameDefault() must not be called with an exception set, - because it can clear it (directly or indirectly) and so the - caller loses its exception */ - assert(!_PyErr_Occurred(tstate)); -#endif - -main_loop: - for (;;) { - assert(stack_pointer >= f->f_valuestack); /* else underflow */ - assert(STACK_LEVEL() <= co->co_stacksize); /* else overflow */ - assert(!_PyErr_Occurred(tstate)); - - /* Do periodic things. Doing this every time through - the loop would add too much overhead, so we do it - only every Nth instruction. We also do it if - ``pending.calls_to_do'' is set, i.e. when an asynchronous - event needs attention (e.g. a signal handler or - async I/O handler); see Py_AddPendingCall() and - Py_MakePendingCalls() above. */ - - if (_Py_atomic_load_relaxed(eval_breaker)) { - opcode = _Py_OPCODE(*next_instr); - if (opcode != SETUP_FINALLY && - opcode != SETUP_WITH && - opcode != BEFORE_ASYNC_WITH && - opcode != YIELD_FROM) { - /* Few cases where we skip running signal handlers and other - pending calls: - - If we're about to enter the 'with:'. It will prevent - emitting a resource warning in the common idiom - 'with open(path) as file:'. - - If we're about to enter the 'async with:'. - - If we're about to enter the 'try:' of a try/finally (not - *very* useful, but might help in some cases and it's - traditional) - - If we're resuming a chain of nested 'yield from' or - 'await' calls, then each frame is parked with YIELD_FROM - as its next opcode. If the user hit control-C we want to - wait until we've reached the innermost frame before - running the signal handler and raising KeyboardInterrupt - (see bpo-30039). - */ - if (eval_frame_handle_pending(tstate) != 0) { - goto error; - } - } - } - - tracing_dispatch: - { - int instr_prev = f->f_lasti; - f->f_lasti = INSTR_OFFSET(); - NEXTOPARG(); - - if (PyDTrace_LINE_ENABLED()) - maybe_dtrace_line(f, &trace_info, instr_prev); - - /* line-by-line tracing support */ - - if (trace_info.cframe.use_tracing && - tstate->c_tracefunc != NULL && !tstate->tracing) { - int err; - /* see maybe_call_line_trace() - for expository comments */ - f->f_stackdepth = (int)(stack_pointer - f->f_valuestack); - - err = maybe_call_line_trace(tstate->c_tracefunc, - tstate->c_traceobj, - tstate, f, - &trace_info, instr_prev); - /* Reload possibly changed frame fields */ - JUMPTO(f->f_lasti); - stack_pointer = f->f_valuestack+f->f_stackdepth; - f->f_stackdepth = -1; - if (err) { - /* trace function raised an exception */ - goto error; - } - NEXTOPARG(); - } - } - -#ifdef LLTRACE - /* Instruction tracing */ - - if (lltrace) { - if (HAS_ARG(opcode)) { - printf("%d: %d, %d\n", - f->f_lasti, opcode, oparg); - } - else { - printf("%d: %d\n", - f->f_lasti, opcode); - } - } -#endif -#if USE_COMPUTED_GOTOS == 0 - goto dispatch_opcode; - - predispatch: - if (trace_info.cframe.use_tracing OR_DTRACE_LINE OR_LLTRACE) { - goto tracing_dispatch; - } - f->f_lasti = INSTR_OFFSET(); - NEXTOPARG(); -#endif - dispatch_opcode: -#ifdef DYNAMIC_EXECUTION_PROFILE -#ifdef DXPAIRS - dxpairs[lastopcode][opcode]++; - lastopcode = opcode; -#endif - dxp[opcode]++; -#endif - - switch (opcode) { - - /* BEWARE! - It is essential that any operation that fails must goto error - and that all operation that succeed call DISPATCH() ! */ - - case TARGET(NOP): { - DISPATCH(); - } - - case TARGET(LOAD_FAST): { - PyObject *value = GETLOCAL(oparg); - if (value == NULL) { - format_exc_check_arg(tstate, PyExc_UnboundLocalError, - UNBOUNDLOCAL_ERROR_MSG, - PyTuple_GetItem(co->co_varnames, oparg)); - goto error; - } - Py_INCREF(value); - PUSH(value); - DISPATCH(); - } - - case TARGET(LOAD_CONST): { - PREDICTED(LOAD_CONST); - PyObject *value = GETITEM(consts, oparg); - Py_INCREF(value); - PUSH(value); - DISPATCH(); - } - - case TARGET(STORE_FAST): { - PREDICTED(STORE_FAST); - PyObject *value = POP(); - SETLOCAL(oparg, value); - DISPATCH(); - } - - case TARGET(POP_TOP): { - PyObject *value = POP(); - Py_DECREF(value); - DISPATCH(); - } - - case TARGET(ROT_TWO): { - PyObject *top = TOP(); - PyObject *second = SECOND(); - SET_TOP(second); - SET_SECOND(top); - DISPATCH(); - } - - case TARGET(ROT_THREE): { - PyObject *top = TOP(); - PyObject *second = SECOND(); - PyObject *third = THIRD(); - SET_TOP(second); - SET_SECOND(third); - SET_THIRD(top); - DISPATCH(); - } - - case TARGET(ROT_FOUR): { - PyObject *top = TOP(); - PyObject *second = SECOND(); - PyObject *third = THIRD(); - PyObject *fourth = FOURTH(); - SET_TOP(second); - SET_SECOND(third); - SET_THIRD(fourth); - SET_FOURTH(top); - DISPATCH(); - } - - case TARGET(DUP_TOP): { - PyObject *top = TOP(); - Py_INCREF(top); - PUSH(top); - DISPATCH(); - } - - case TARGET(DUP_TOP_TWO): { - PyObject *top = TOP(); - PyObject *second = SECOND(); - Py_INCREF(top); - Py_INCREF(second); - STACK_GROW(2); - SET_TOP(top); - SET_SECOND(second); - DISPATCH(); - } - - case TARGET(UNARY_POSITIVE): { - PyObject *value = TOP(); - PyObject *res = PyNumber_Positive(value); - Py_DECREF(value); - SET_TOP(res); - if (res == NULL) - goto error; - DISPATCH(); - } - - case TARGET(UNARY_NEGATIVE): { - PyObject *value = TOP(); - PyObject *res = PyNumber_Negative(value); - Py_DECREF(value); - SET_TOP(res); - if (res == NULL) - goto error; - DISPATCH(); - } - - case TARGET(UNARY_NOT): { - PyObject *value = TOP(); - int err = PyObject_IsTrue(value); - Py_DECREF(value); - if (err == 0) { - Py_INCREF(Py_True); - SET_TOP(Py_True); - DISPATCH(); - } - else if (err > 0) { - Py_INCREF(Py_False); - SET_TOP(Py_False); - DISPATCH(); - } - STACK_SHRINK(1); - goto error; - } - - case TARGET(UNARY_INVERT): { - PyObject *value = TOP(); - PyObject *res = PyNumber_Invert(value); - Py_DECREF(value); - SET_TOP(res); - if (res == NULL) - goto error; - DISPATCH(); - } - - case TARGET(BINARY_POWER): { - PyObject *exp = POP(); - PyObject *base = TOP(); - PyObject *res = PyNumber_Power(base, exp, Py_None); - Py_DECREF(base); - Py_DECREF(exp); - SET_TOP(res); - if (res == NULL) - goto error; - DISPATCH(); - } - - case TARGET(BINARY_MULTIPLY): { - PyObject *right = POP(); - PyObject *left = TOP(); - PyObject *res = PyNumber_Multiply(left, right); - Py_DECREF(left); - Py_DECREF(right); - SET_TOP(res); - if (res == NULL) - goto error; - DISPATCH(); - } - - case TARGET(BINARY_MATRIX_MULTIPLY): { - PyObject *right = POP(); - PyObject *left = TOP(); - PyObject *res = PyNumber_MatrixMultiply(left, right); - Py_DECREF(left); - Py_DECREF(right); - SET_TOP(res); - if (res == NULL) - goto error; - DISPATCH(); - } - - case TARGET(BINARY_TRUE_DIVIDE): { - PyObject *divisor = POP(); - PyObject *dividend = TOP(); - PyObject *quotient = PyNumber_TrueDivide(dividend, divisor); - Py_DECREF(dividend); - Py_DECREF(divisor); - SET_TOP(quotient); - if (quotient == NULL) - goto error; - DISPATCH(); - } - - case TARGET(BINARY_FLOOR_DIVIDE): { - PyObject *divisor = POP(); - PyObject *dividend = TOP(); - PyObject *quotient = PyNumber_FloorDivide(dividend, divisor); - Py_DECREF(dividend); - Py_DECREF(divisor); - SET_TOP(quotient); - if (quotient == NULL) - goto error; - DISPATCH(); - } - - case TARGET(BINARY_MODULO): { - PyObject *divisor = POP(); - PyObject *dividend = TOP(); - PyObject *res; - if (PyUnicode_CheckExact(dividend) && ( - !PyUnicode_Check(divisor) || PyUnicode_CheckExact(divisor))) { - // fast path; string formatting, but not if the RHS is a str subclass - // (see issue28598) - res = PyUnicode_Format(dividend, divisor); - } else { - res = PyNumber_Remainder(dividend, divisor); - } - Py_DECREF(divisor); - Py_DECREF(dividend); - SET_TOP(res); - if (res == NULL) - goto error; - DISPATCH(); - } - - case TARGET(BINARY_ADD): { - PyObject *right = POP(); - PyObject *left = TOP(); - PyObject *sum; - /* NOTE(vstinner): Please don't try to micro-optimize int+int on - CPython using bytecode, it is simply worthless. - See http://bugs.python.org/issue21955 and - http://bugs.python.org/issue10044 for the discussion. In short, - no patch shown any impact on a realistic benchmark, only a minor - speedup on microbenchmarks. */ - if (PyUnicode_CheckExact(left) && - PyUnicode_CheckExact(right)) { - sum = unicode_concatenate(tstate, left, right, f, next_instr); - /* unicode_concatenate consumed the ref to left */ - } - else { - sum = PyNumber_Add(left, right); - Py_DECREF(left); - } - Py_DECREF(right); - SET_TOP(sum); - if (sum == NULL) - goto error; - DISPATCH(); - } - - case TARGET(BINARY_SUBTRACT): { - PyObject *right = POP(); - PyObject *left = TOP(); - PyObject *diff = PyNumber_Subtract(left, right); - Py_DECREF(right); - Py_DECREF(left); - SET_TOP(diff); - if (diff == NULL) - goto error; - DISPATCH(); - } - - case TARGET(BINARY_SUBSCR): { - PyObject *sub = POP(); - PyObject *container = TOP(); - PyObject *res = PyObject_GetItem(container, sub); - Py_DECREF(container); - Py_DECREF(sub); - SET_TOP(res); - if (res == NULL) - goto error; - DISPATCH(); - } - - case TARGET(BINARY_LSHIFT): { - PyObject *right = POP(); - PyObject *left = TOP(); - PyObject *res = PyNumber_Lshift(left, right); - Py_DECREF(left); - Py_DECREF(right); - SET_TOP(res); - if (res == NULL) - goto error; - DISPATCH(); - } - - case TARGET(BINARY_RSHIFT): { - PyObject *right = POP(); - PyObject *left = TOP(); - PyObject *res = PyNumber_Rshift(left, right); - Py_DECREF(left); - Py_DECREF(right); - SET_TOP(res); - if (res == NULL) - goto error; - DISPATCH(); - } - - case TARGET(BINARY_AND): { - PyObject *right = POP(); - PyObject *left = TOP(); - PyObject *res = PyNumber_And(left, right); - Py_DECREF(left); - Py_DECREF(right); - SET_TOP(res); - if (res == NULL) - goto error; - DISPATCH(); - } - - case TARGET(BINARY_XOR): { - PyObject *right = POP(); - PyObject *left = TOP(); - PyObject *res = PyNumber_Xor(left, right); - Py_DECREF(left); - Py_DECREF(right); - SET_TOP(res); - if (res == NULL) - goto error; - DISPATCH(); - } - - case TARGET(BINARY_OR): { - PyObject *right = POP(); - PyObject *left = TOP(); - PyObject *res = PyNumber_Or(left, right); - Py_DECREF(left); - Py_DECREF(right); - SET_TOP(res); - if (res == NULL) - goto error; - DISPATCH(); - } - - case TARGET(LIST_APPEND): { - PyObject *v = POP(); - PyObject *list = PEEK(oparg); - int err; - err = PyList_Append(list, v); - Py_DECREF(v); - if (err != 0) - goto error; - PREDICT(JUMP_ABSOLUTE); - DISPATCH(); - } - - case TARGET(SET_ADD): { - PyObject *v = POP(); - PyObject *set = PEEK(oparg); - int err; - err = PySet_Add(set, v); - Py_DECREF(v); - if (err != 0) - goto error; - PREDICT(JUMP_ABSOLUTE); - DISPATCH(); - } - - case TARGET(INPLACE_POWER): { - PyObject *exp = POP(); - PyObject *base = TOP(); - PyObject *res = PyNumber_InPlacePower(base, exp, Py_None); - Py_DECREF(base); - Py_DECREF(exp); - SET_TOP(res); - if (res == NULL) - goto error; - DISPATCH(); - } - - case TARGET(INPLACE_MULTIPLY): { - PyObject *right = POP(); - PyObject *left = TOP(); - PyObject *res = PyNumber_InPlaceMultiply(left, right); - Py_DECREF(left); - Py_DECREF(right); - SET_TOP(res); - if (res == NULL) - goto error; - DISPATCH(); - } - - case TARGET(INPLACE_MATRIX_MULTIPLY): { - PyObject *right = POP(); - PyObject *left = TOP(); - PyObject *res = PyNumber_InPlaceMatrixMultiply(left, right); - Py_DECREF(left); - Py_DECREF(right); - SET_TOP(res); - if (res == NULL) - goto error; - DISPATCH(); - } - - case TARGET(INPLACE_TRUE_DIVIDE): { - PyObject *divisor = POP(); - PyObject *dividend = TOP(); - PyObject *quotient = PyNumber_InPlaceTrueDivide(dividend, divisor); - Py_DECREF(dividend); - Py_DECREF(divisor); - SET_TOP(quotient); - if (quotient == NULL) - goto error; - DISPATCH(); - } - - case TARGET(INPLACE_FLOOR_DIVIDE): { - PyObject *divisor = POP(); - PyObject *dividend = TOP(); - PyObject *quotient = PyNumber_InPlaceFloorDivide(dividend, divisor); - Py_DECREF(dividend); - Py_DECREF(divisor); - SET_TOP(quotient); - if (quotient == NULL) - goto error; - DISPATCH(); - } - - case TARGET(INPLACE_MODULO): { - PyObject *right = POP(); - PyObject *left = TOP(); - PyObject *mod = PyNumber_InPlaceRemainder(left, right); - Py_DECREF(left); - Py_DECREF(right); - SET_TOP(mod); - if (mod == NULL) - goto error; - DISPATCH(); - } - - case TARGET(INPLACE_ADD): { - PyObject *right = POP(); - PyObject *left = TOP(); - PyObject *sum; - if (PyUnicode_CheckExact(left) && PyUnicode_CheckExact(right)) { - sum = unicode_concatenate(tstate, left, right, f, next_instr); - /* unicode_concatenate consumed the ref to left */ - } - else { - sum = PyNumber_InPlaceAdd(left, right); - Py_DECREF(left); - } - Py_DECREF(right); - SET_TOP(sum); - if (sum == NULL) - goto error; - DISPATCH(); - } - - case TARGET(INPLACE_SUBTRACT): { - PyObject *right = POP(); - PyObject *left = TOP(); - PyObject *diff = PyNumber_InPlaceSubtract(left, right); - Py_DECREF(left); - Py_DECREF(right); - SET_TOP(diff); - if (diff == NULL) - goto error; - DISPATCH(); - } - - case TARGET(INPLACE_LSHIFT): { - PyObject *right = POP(); - PyObject *left = TOP(); - PyObject *res = PyNumber_InPlaceLshift(left, right); - Py_DECREF(left); - Py_DECREF(right); - SET_TOP(res); - if (res == NULL) - goto error; - DISPATCH(); - } - - case TARGET(INPLACE_RSHIFT): { - PyObject *right = POP(); - PyObject *left = TOP(); - PyObject *res = PyNumber_InPlaceRshift(left, right); - Py_DECREF(left); - Py_DECREF(right); - SET_TOP(res); - if (res == NULL) - goto error; - DISPATCH(); - } - - case TARGET(INPLACE_AND): { - PyObject *right = POP(); - PyObject *left = TOP(); - PyObject *res = PyNumber_InPlaceAnd(left, right); - Py_DECREF(left); - Py_DECREF(right); - SET_TOP(res); - if (res == NULL) - goto error; - DISPATCH(); - } - - case TARGET(INPLACE_XOR): { - PyObject *right = POP(); - PyObject *left = TOP(); - PyObject *res = PyNumber_InPlaceXor(left, right); - Py_DECREF(left); - Py_DECREF(right); - SET_TOP(res); - if (res == NULL) - goto error; - DISPATCH(); - } - - case TARGET(INPLACE_OR): { - PyObject *right = POP(); - PyObject *left = TOP(); - PyObject *res = PyNumber_InPlaceOr(left, right); - Py_DECREF(left); - Py_DECREF(right); - SET_TOP(res); - if (res == NULL) - goto error; - DISPATCH(); - } - - case TARGET(STORE_SUBSCR): { - PyObject *sub = TOP(); - PyObject *container = SECOND(); - PyObject *v = THIRD(); - int err; - STACK_SHRINK(3); - /* container[sub] = v */ - err = PyObject_SetItem(container, sub, v); - Py_DECREF(v); - Py_DECREF(container); - Py_DECREF(sub); - if (err != 0) - goto error; - DISPATCH(); - } - - case TARGET(DELETE_SUBSCR): { - PyObject *sub = TOP(); - PyObject *container = SECOND(); - int err; - STACK_SHRINK(2); - /* del container[sub] */ - err = PyObject_DelItem(container, sub); - Py_DECREF(container); - Py_DECREF(sub); - if (err != 0) - goto error; - DISPATCH(); - } - - case TARGET(PRINT_EXPR): { - _Py_IDENTIFIER(displayhook); - PyObject *value = POP(); - PyObject *hook = _PySys_GetObjectId(&PyId_displayhook); - PyObject *res; - if (hook == NULL) { - _PyErr_SetString(tstate, PyExc_RuntimeError, - "lost sys.displayhook"); - Py_DECREF(value); - goto error; - } - res = PyObject_CallOneArg(hook, value); - Py_DECREF(value); - if (res == NULL) - goto error; - Py_DECREF(res); - DISPATCH(); - } - - case TARGET(RAISE_VARARGS): { - PyObject *cause = NULL, *exc = NULL; - switch (oparg) { - case 2: - cause = POP(); /* cause */ - /* fall through */ - case 1: - exc = POP(); /* exc */ - /* fall through */ - case 0: - if (do_raise(tstate, exc, cause)) { - goto exception_unwind; - } - break; - default: - _PyErr_SetString(tstate, PyExc_SystemError, - "bad RAISE_VARARGS oparg"); - break; - } - goto error; - } - - case TARGET(RETURN_VALUE): { - retval = POP(); - assert(f->f_iblock == 0); - assert(EMPTY()); - f->f_state = FRAME_RETURNED; - f->f_stackdepth = 0; - goto exiting; - } - - case TARGET(GET_AITER): { - unaryfunc getter = NULL; - PyObject *iter = NULL; - PyObject *obj = TOP(); - PyTypeObject *type = Py_TYPE(obj); - - if (type->tp_as_async != NULL) { - getter = type->tp_as_async->am_aiter; - } - - if (getter != NULL) { - iter = (*getter)(obj); - Py_DECREF(obj); - if (iter == NULL) { - SET_TOP(NULL); - goto error; - } - } - else { - SET_TOP(NULL); - _PyErr_Format(tstate, PyExc_TypeError, - "'async for' requires an object with " - "__aiter__ method, got %.100s", - type->tp_name); - Py_DECREF(obj); - goto error; - } - - if (Py_TYPE(iter)->tp_as_async == NULL || - Py_TYPE(iter)->tp_as_async->am_anext == NULL) { - - SET_TOP(NULL); - _PyErr_Format(tstate, PyExc_TypeError, - "'async for' received an object from __aiter__ " - "that does not implement __anext__: %.100s", - Py_TYPE(iter)->tp_name); - Py_DECREF(iter); - goto error; - } - - SET_TOP(iter); - DISPATCH(); - } - - case TARGET(GET_ANEXT): { - unaryfunc getter = NULL; - PyObject *next_iter = NULL; - PyObject *awaitable = NULL; - PyObject *aiter = TOP(); - PyTypeObject *type = Py_TYPE(aiter); - - if (PyAsyncGen_CheckExact(aiter)) { - awaitable = type->tp_as_async->am_anext(aiter); - if (awaitable == NULL) { - goto error; - } - } else { - if (type->tp_as_async != NULL){ - getter = type->tp_as_async->am_anext; - } - - if (getter != NULL) { - next_iter = (*getter)(aiter); - if (next_iter == NULL) { - goto error; - } - } - else { - _PyErr_Format(tstate, PyExc_TypeError, - "'async for' requires an iterator with " - "__anext__ method, got %.100s", - type->tp_name); - goto error; - } - - awaitable = _PyCoro_GetAwaitableIter(next_iter); - if (awaitable == NULL) { - _PyErr_FormatFromCause( - PyExc_TypeError, - "'async for' received an invalid object " - "from __anext__: %.100s", - Py_TYPE(next_iter)->tp_name); - - Py_DECREF(next_iter); - goto error; - } else { - Py_DECREF(next_iter); - } - } - - PUSH(awaitable); - PREDICT(LOAD_CONST); - DISPATCH(); - } - - case TARGET(GET_AWAITABLE): { - PREDICTED(GET_AWAITABLE); - PyObject *iterable = TOP(); - PyObject *iter = _PyCoro_GetAwaitableIter(iterable); - - if (iter == NULL) { - int opcode_at_minus_3 = 0; - if ((next_instr - first_instr) > 2) { - opcode_at_minus_3 = _Py_OPCODE(next_instr[-3]); - } - format_awaitable_error(tstate, Py_TYPE(iterable), - opcode_at_minus_3, - _Py_OPCODE(next_instr[-2])); - } - - Py_DECREF(iterable); - - if (iter != NULL && PyCoro_CheckExact(iter)) { - PyObject *yf = _PyGen_yf((PyGenObject*)iter); - if (yf != NULL) { - /* `iter` is a coroutine object that is being - awaited, `yf` is a pointer to the current awaitable - being awaited on. */ - Py_DECREF(yf); - Py_CLEAR(iter); - _PyErr_SetString(tstate, PyExc_RuntimeError, - "coroutine is being awaited already"); - /* The code below jumps to `error` if `iter` is NULL. */ - } - } - - SET_TOP(iter); /* Even if it's NULL */ - - if (iter == NULL) { - goto error; - } - - PREDICT(LOAD_CONST); - DISPATCH(); - } - - case TARGET(YIELD_FROM): { - PyObject *v = POP(); - PyObject *receiver = TOP(); - PySendResult gen_status; - if (tstate->c_tracefunc == NULL) { - gen_status = PyIter_Send(receiver, v, &retval); - } else { - _Py_IDENTIFIER(send); - if (Py_IsNone(v) && PyIter_Check(receiver)) { - retval = Py_TYPE(receiver)->tp_iternext(receiver); - } - else { - retval = _PyObject_CallMethodIdOneArg(receiver, &PyId_send, v); - } - if (retval == NULL) { - if (tstate->c_tracefunc != NULL - && _PyErr_ExceptionMatches(tstate, PyExc_StopIteration)) - call_exc_trace(tstate->c_tracefunc, tstate->c_traceobj, tstate, f, &trace_info); - if (_PyGen_FetchStopIterationValue(&retval) == 0) { - gen_status = PYGEN_RETURN; - } - else { - gen_status = PYGEN_ERROR; - } - } - else { - gen_status = PYGEN_NEXT; - } - } - Py_DECREF(v); - if (gen_status == PYGEN_ERROR) { - assert (retval == NULL); - goto error; - } - if (gen_status == PYGEN_RETURN) { - assert (retval != NULL); - - Py_DECREF(receiver); - SET_TOP(retval); - retval = NULL; - DISPATCH(); - } - assert (gen_status == PYGEN_NEXT); - /* receiver remains on stack, retval is value to be yielded */ - /* and repeat... */ - assert(f->f_lasti > 0); - f->f_lasti -= 1; - f->f_state = FRAME_SUSPENDED; - f->f_stackdepth = (int)(stack_pointer - f->f_valuestack); - goto exiting; - } - - case TARGET(YIELD_VALUE): { - retval = POP(); - - if (co->co_flags & CO_ASYNC_GENERATOR) { - PyObject *w = _PyAsyncGenValueWrapperNew(retval); - Py_DECREF(retval); - if (w == NULL) { - retval = NULL; - goto error; - } - retval = w; - } - f->f_state = FRAME_SUSPENDED; - f->f_stackdepth = (int)(stack_pointer - f->f_valuestack); - goto exiting; - } - - case TARGET(GEN_START): { - PyObject *none = POP(); - assert(none == Py_None); - assert(oparg < 3); - Py_DECREF(none); - DISPATCH(); - } - - case TARGET(POP_EXCEPT): { - PyObject *type, *value, *traceback; - _PyErr_StackItem *exc_info; - PyTryBlock *b = PyFrame_BlockPop(f); - if (b->b_type != EXCEPT_HANDLER) { - _PyErr_SetString(tstate, PyExc_SystemError, - "popped block is not an except handler"); - goto error; - } - assert(STACK_LEVEL() >= (b)->b_level + 3 && - STACK_LEVEL() <= (b)->b_level + 4); - exc_info = tstate->exc_info; - type = exc_info->exc_type; - value = exc_info->exc_value; - traceback = exc_info->exc_traceback; - exc_info->exc_type = POP(); - exc_info->exc_value = POP(); - exc_info->exc_traceback = POP(); - Py_XDECREF(type); - Py_XDECREF(value); - Py_XDECREF(traceback); - DISPATCH(); - } - - case TARGET(POP_BLOCK): { - PyFrame_BlockPop(f); - DISPATCH(); - } - - case TARGET(RERAISE): { - assert(f->f_iblock > 0); - if (oparg) { - f->f_lasti = f->f_blockstack[f->f_iblock-1].b_handler; - } - PyObject *exc = POP(); - PyObject *val = POP(); - PyObject *tb = POP(); - assert(PyExceptionClass_Check(exc)); - _PyErr_Restore(tstate, exc, val, tb); - goto exception_unwind; - } - - case TARGET(END_ASYNC_FOR): { - PyObject *exc = POP(); - assert(PyExceptionClass_Check(exc)); - if (PyErr_GivenExceptionMatches(exc, PyExc_StopAsyncIteration)) { - PyTryBlock *b = PyFrame_BlockPop(f); - assert(b->b_type == EXCEPT_HANDLER); - Py_DECREF(exc); - UNWIND_EXCEPT_HANDLER(b); - Py_DECREF(POP()); - JUMPBY(oparg); - DISPATCH(); - } - else { - PyObject *val = POP(); - PyObject *tb = POP(); - _PyErr_Restore(tstate, exc, val, tb); - goto exception_unwind; - } - } - - case TARGET(LOAD_ASSERTION_ERROR): { - PyObject *value = PyExc_AssertionError; - Py_INCREF(value); - PUSH(value); - DISPATCH(); - } - - case TARGET(LOAD_BUILD_CLASS): { - _Py_IDENTIFIER(__build_class__); - - PyObject *bc; - if (PyDict_CheckExact(f->f_builtins)) { - bc = _PyDict_GetItemIdWithError(f->f_builtins, &PyId___build_class__); - if (bc == NULL) { - if (!_PyErr_Occurred(tstate)) { - _PyErr_SetString(tstate, PyExc_NameError, - "__build_class__ not found"); - } - goto error; - } - Py_INCREF(bc); - } - else { - PyObject *build_class_str = _PyUnicode_FromId(&PyId___build_class__); - if (build_class_str == NULL) - goto error; - bc = PyObject_GetItem(f->f_builtins, build_class_str); - if (bc == NULL) { - if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) - _PyErr_SetString(tstate, PyExc_NameError, - "__build_class__ not found"); - goto error; - } - } - PUSH(bc); - DISPATCH(); - } - - case TARGET(STORE_NAME): { - PyObject *name = GETITEM(names, oparg); - PyObject *v = POP(); - PyObject *ns = f->f_locals; - int err; - if (ns == NULL) { - _PyErr_Format(tstate, PyExc_SystemError, - "no locals found when storing %R", name); - Py_DECREF(v); - goto error; - } - if (PyDict_CheckExact(ns)) - err = PyDict_SetItem(ns, name, v); - else - err = PyObject_SetItem(ns, name, v); - Py_DECREF(v); - if (err != 0) - goto error; - DISPATCH(); - } - - case TARGET(DELETE_NAME): { - PyObject *name = GETITEM(names, oparg); - PyObject *ns = f->f_locals; - int err; - if (ns == NULL) { - _PyErr_Format(tstate, PyExc_SystemError, - "no locals when deleting %R", name); - goto error; - } - err = PyObject_DelItem(ns, name); - if (err != 0) { - format_exc_check_arg(tstate, PyExc_NameError, - NAME_ERROR_MSG, - name); - goto error; - } - DISPATCH(); - } - - case TARGET(UNPACK_SEQUENCE): { - PREDICTED(UNPACK_SEQUENCE); - PyObject *seq = POP(), *item, **items; - if (PyTuple_CheckExact(seq) && - PyTuple_GET_SIZE(seq) == oparg) { - items = ((PyTupleObject *)seq)->ob_item; - while (oparg--) { - item = items[oparg]; - Py_INCREF(item); - PUSH(item); - } - } else if (PyList_CheckExact(seq) && - PyList_GET_SIZE(seq) == oparg) { - items = ((PyListObject *)seq)->ob_item; - while (oparg--) { - item = items[oparg]; - Py_INCREF(item); - PUSH(item); - } - } else if (unpack_iterable(tstate, seq, oparg, -1, - stack_pointer + oparg)) { - STACK_GROW(oparg); - } else { - /* unpack_iterable() raised an exception */ - Py_DECREF(seq); - goto error; - } - Py_DECREF(seq); - DISPATCH(); - } - - case TARGET(UNPACK_EX): { - int totalargs = 1 + (oparg & 0xFF) + (oparg >> 8); - PyObject *seq = POP(); - - if (unpack_iterable(tstate, seq, oparg & 0xFF, oparg >> 8, - stack_pointer + totalargs)) { - stack_pointer += totalargs; - } else { - Py_DECREF(seq); - goto error; - } - Py_DECREF(seq); - DISPATCH(); - } - - case TARGET(STORE_ATTR): { - PyObject *name = GETITEM(names, oparg); - PyObject *owner = TOP(); - PyObject *v = SECOND(); - int err; - STACK_SHRINK(2); - err = PyObject_SetAttr(owner, name, v); - Py_DECREF(v); - Py_DECREF(owner); - if (err != 0) - goto error; - DISPATCH(); - } - - case TARGET(DELETE_ATTR): { - PyObject *name = GETITEM(names, oparg); - PyObject *owner = POP(); - int err; - err = PyObject_SetAttr(owner, name, (PyObject *)NULL); - Py_DECREF(owner); - if (err != 0) - goto error; - DISPATCH(); - } - - case TARGET(STORE_GLOBAL): { - PyObject *name = GETITEM(names, oparg); - PyObject *v = POP(); - int err; - err = PyDict_SetItem(f->f_globals, name, v); - Py_DECREF(v); - if (err != 0) - goto error; - DISPATCH(); - } - - case TARGET(DELETE_GLOBAL): { - PyObject *name = GETITEM(names, oparg); - int err; - err = PyDict_DelItem(f->f_globals, name); - if (err != 0) { - if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { - format_exc_check_arg(tstate, PyExc_NameError, - NAME_ERROR_MSG, name); - } - goto error; - } - DISPATCH(); - } - - case TARGET(LOAD_NAME): { - PyObject *name = GETITEM(names, oparg); - PyObject *locals = f->f_locals; - PyObject *v; - if (locals == NULL) { - _PyErr_Format(tstate, PyExc_SystemError, - "no locals when loading %R", name); - goto error; - } - if (PyDict_CheckExact(locals)) { - v = PyDict_GetItemWithError(locals, name); - if (v != NULL) { - Py_INCREF(v); - } - else if (_PyErr_Occurred(tstate)) { - goto error; - } - } - else { - v = PyObject_GetItem(locals, name); - if (v == NULL) { - if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) - goto error; - _PyErr_Clear(tstate); - } - } - if (v == NULL) { - v = PyDict_GetItemWithError(f->f_globals, name); - if (v != NULL) { - Py_INCREF(v); - } - else if (_PyErr_Occurred(tstate)) { - goto error; - } - else { - if (PyDict_CheckExact(f->f_builtins)) { - v = PyDict_GetItemWithError(f->f_builtins, name); - if (v == NULL) { - if (!_PyErr_Occurred(tstate)) { - format_exc_check_arg( - tstate, PyExc_NameError, - NAME_ERROR_MSG, name); - } - goto error; - } - Py_INCREF(v); - } - else { - v = PyObject_GetItem(f->f_builtins, name); - if (v == NULL) { - if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { - format_exc_check_arg( - tstate, PyExc_NameError, - NAME_ERROR_MSG, name); - } - goto error; - } - } - } - } - PUSH(v); - DISPATCH(); - } - - case TARGET(LOAD_GLOBAL): { - PyObject *name; - PyObject *v; - if (PyDict_CheckExact(f->f_globals) - && PyDict_CheckExact(f->f_builtins)) - { - OPCACHE_CHECK(); - if (co_opcache != NULL && co_opcache->optimized > 0) { - _PyOpcache_LoadGlobal *lg = &co_opcache->u.lg; - - if (lg->globals_ver == - ((PyDictObject *)f->f_globals)->ma_version_tag - && lg->builtins_ver == - ((PyDictObject *)f->f_builtins)->ma_version_tag) - { - PyObject *ptr = lg->ptr; - OPCACHE_STAT_GLOBAL_HIT(); - assert(ptr != NULL); - Py_INCREF(ptr); - PUSH(ptr); - DISPATCH(); - } - } - - name = GETITEM(names, oparg); - v = _PyDict_LoadGlobal((PyDictObject *)f->f_globals, - (PyDictObject *)f->f_builtins, - name); - if (v == NULL) { - if (!_PyErr_Occurred(tstate)) { - /* _PyDict_LoadGlobal() returns NULL without raising - * an exception if the key doesn't exist */ - format_exc_check_arg(tstate, PyExc_NameError, - NAME_ERROR_MSG, name); - } - goto error; - } - - if (co_opcache != NULL) { - _PyOpcache_LoadGlobal *lg = &co_opcache->u.lg; - - if (co_opcache->optimized == 0) { - /* Wasn't optimized before. */ - OPCACHE_STAT_GLOBAL_OPT(); - } else { - OPCACHE_STAT_GLOBAL_MISS(); - } - - co_opcache->optimized = 1; - lg->globals_ver = - ((PyDictObject *)f->f_globals)->ma_version_tag; - lg->builtins_ver = - ((PyDictObject *)f->f_builtins)->ma_version_tag; - lg->ptr = v; /* borrowed */ - } - - Py_INCREF(v); - } - else { - /* Slow-path if globals or builtins is not a dict */ - - /* namespace 1: globals */ - name = GETITEM(names, oparg); - v = PyObject_GetItem(f->f_globals, name); - if (v == NULL) { - if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { - goto error; - } - _PyErr_Clear(tstate); - - /* namespace 2: builtins */ - v = PyObject_GetItem(f->f_builtins, name); - if (v == NULL) { - if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { - format_exc_check_arg( - tstate, PyExc_NameError, - NAME_ERROR_MSG, name); - } - goto error; - } - } - } - PUSH(v); - DISPATCH(); - } - - case TARGET(DELETE_FAST): { - PyObject *v = GETLOCAL(oparg); - if (v != NULL) { - SETLOCAL(oparg, NULL); - DISPATCH(); - } - format_exc_check_arg( - tstate, PyExc_UnboundLocalError, - UNBOUNDLOCAL_ERROR_MSG, - PyTuple_GetItem(co->co_varnames, oparg) - ); - goto error; - } - - case TARGET(DELETE_DEREF): { - PyObject *cell = freevars[oparg]; - PyObject *oldobj = PyCell_GET(cell); - if (oldobj != NULL) { - PyCell_SET(cell, NULL); - Py_DECREF(oldobj); - DISPATCH(); - } - format_exc_unbound(tstate, co, oparg); - goto error; - } - - case TARGET(LOAD_CLOSURE): { - PyObject *cell = freevars[oparg]; - Py_INCREF(cell); - PUSH(cell); - DISPATCH(); - } - - case TARGET(LOAD_CLASSDEREF): { - PyObject *name, *value, *locals = f->f_locals; - Py_ssize_t idx; - assert(locals); - assert(oparg >= PyTuple_GET_SIZE(co->co_cellvars)); - idx = oparg - PyTuple_GET_SIZE(co->co_cellvars); - assert(idx >= 0 && idx < PyTuple_GET_SIZE(co->co_freevars)); - name = PyTuple_GET_ITEM(co->co_freevars, idx); - if (PyDict_CheckExact(locals)) { - value = PyDict_GetItemWithError(locals, name); - if (value != NULL) { - Py_INCREF(value); - } - else if (_PyErr_Occurred(tstate)) { - goto error; - } - } - else { - value = PyObject_GetItem(locals, name); - if (value == NULL) { - if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { - goto error; - } - _PyErr_Clear(tstate); - } - } - if (!value) { - PyObject *cell = freevars[oparg]; - value = PyCell_GET(cell); - if (value == NULL) { - format_exc_unbound(tstate, co, oparg); - goto error; - } - Py_INCREF(value); - } - PUSH(value); - DISPATCH(); - } - - case TARGET(LOAD_DEREF): { - PyObject *cell = freevars[oparg]; - PyObject *value = PyCell_GET(cell); - if (value == NULL) { - format_exc_unbound(tstate, co, oparg); - goto error; - } - Py_INCREF(value); - PUSH(value); - DISPATCH(); - } - - case TARGET(STORE_DEREF): { - PyObject *v = POP(); - PyObject *cell = freevars[oparg]; - PyObject *oldobj = PyCell_GET(cell); - PyCell_SET(cell, v); - Py_XDECREF(oldobj); - DISPATCH(); - } - - case TARGET(BUILD_STRING): { - PyObject *str; - PyObject *empty = PyUnicode_New(0, 0); - if (empty == NULL) { - goto error; - } - str = _PyUnicode_JoinArray(empty, stack_pointer - oparg, oparg); - Py_DECREF(empty); - if (str == NULL) - goto error; - while (--oparg >= 0) { - PyObject *item = POP(); - Py_DECREF(item); - } - PUSH(str); - DISPATCH(); - } - - case TARGET(BUILD_TUPLE): { - PyObject *tup = PyTuple_New(oparg); - if (tup == NULL) - goto error; - while (--oparg >= 0) { - PyObject *item = POP(); - PyTuple_SET_ITEM(tup, oparg, item); - } - PUSH(tup); - DISPATCH(); - } - - case TARGET(BUILD_LIST): { - PyObject *list = PyList_New(oparg); - if (list == NULL) - goto error; - while (--oparg >= 0) { - PyObject *item = POP(); - PyList_SET_ITEM(list, oparg, item); - } - PUSH(list); - DISPATCH(); - } - - case TARGET(LIST_TO_TUPLE): { - PyObject *list = POP(); - PyObject *tuple = PyList_AsTuple(list); - Py_DECREF(list); - if (tuple == NULL) { - goto error; - } - PUSH(tuple); - DISPATCH(); - } - - case TARGET(LIST_EXTEND): { - PyObject *iterable = POP(); - PyObject *list = PEEK(oparg); - PyObject *none_val = _PyList_Extend((PyListObject *)list, iterable); - if (none_val == NULL) { - if (_PyErr_ExceptionMatches(tstate, PyExc_TypeError) && - (Py_TYPE(iterable)->tp_iter == NULL && !PySequence_Check(iterable))) - { - _PyErr_Clear(tstate); - _PyErr_Format(tstate, PyExc_TypeError, - "Value after * must be an iterable, not %.200s", - Py_TYPE(iterable)->tp_name); - } - Py_DECREF(iterable); - goto error; - } - Py_DECREF(none_val); - Py_DECREF(iterable); - DISPATCH(); - } - - case TARGET(SET_UPDATE): { - PyObject *iterable = POP(); - PyObject *set = PEEK(oparg); - int err = _PySet_Update(set, iterable); - Py_DECREF(iterable); - if (err < 0) { - goto error; - } - DISPATCH(); - } - - case TARGET(BUILD_SET): { - PyObject *set = PySet_New(NULL); - int err = 0; - int i; - if (set == NULL) - goto error; - for (i = oparg; i > 0; i--) { - PyObject *item = PEEK(i); - if (err == 0) - err = PySet_Add(set, item); - Py_DECREF(item); - } - STACK_SHRINK(oparg); - if (err != 0) { - Py_DECREF(set); - goto error; - } - PUSH(set); - DISPATCH(); - } - - case TARGET(BUILD_MAP): { - Py_ssize_t i; - PyObject *map = _PyDict_NewPresized((Py_ssize_t)oparg); - if (map == NULL) - goto error; - for (i = oparg; i > 0; i--) { - int err; - PyObject *key = PEEK(2*i); - PyObject *value = PEEK(2*i - 1); - err = PyDict_SetItem(map, key, value); - if (err != 0) { - Py_DECREF(map); - goto error; - } - } - - while (oparg--) { - Py_DECREF(POP()); - Py_DECREF(POP()); - } - PUSH(map); - DISPATCH(); - } - - case TARGET(SETUP_ANNOTATIONS): { - _Py_IDENTIFIER(__annotations__); - int err; - PyObject *ann_dict; - if (f->f_locals == NULL) { - _PyErr_Format(tstate, PyExc_SystemError, - "no locals found when setting up annotations"); - goto error; - } - /* check if __annotations__ in locals()... */ - if (PyDict_CheckExact(f->f_locals)) { - ann_dict = _PyDict_GetItemIdWithError(f->f_locals, - &PyId___annotations__); - if (ann_dict == NULL) { - if (_PyErr_Occurred(tstate)) { - goto error; - } - /* ...if not, create a new one */ - ann_dict = PyDict_New(); - if (ann_dict == NULL) { - goto error; - } - err = _PyDict_SetItemId(f->f_locals, - &PyId___annotations__, ann_dict); - Py_DECREF(ann_dict); - if (err != 0) { - goto error; - } - } - } - else { - /* do the same if locals() is not a dict */ - PyObject *ann_str = _PyUnicode_FromId(&PyId___annotations__); - if (ann_str == NULL) { - goto error; - } - ann_dict = PyObject_GetItem(f->f_locals, ann_str); - if (ann_dict == NULL) { - if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { - goto error; - } - _PyErr_Clear(tstate); - ann_dict = PyDict_New(); - if (ann_dict == NULL) { - goto error; - } - err = PyObject_SetItem(f->f_locals, ann_str, ann_dict); - Py_DECREF(ann_dict); - if (err != 0) { - goto error; - } - } - else { - Py_DECREF(ann_dict); - } - } - DISPATCH(); - } - - case TARGET(BUILD_CONST_KEY_MAP): { - Py_ssize_t i; - PyObject *map; - PyObject *keys = TOP(); - if (!PyTuple_CheckExact(keys) || - PyTuple_GET_SIZE(keys) != (Py_ssize_t)oparg) { - _PyErr_SetString(tstate, PyExc_SystemError, - "bad BUILD_CONST_KEY_MAP keys argument"); - goto error; - } - map = _PyDict_NewPresized((Py_ssize_t)oparg); - if (map == NULL) { - goto error; - } - for (i = oparg; i > 0; i--) { - int err; - PyObject *key = PyTuple_GET_ITEM(keys, oparg - i); - PyObject *value = PEEK(i + 1); - err = PyDict_SetItem(map, key, value); - if (err != 0) { - Py_DECREF(map); - goto error; - } - } - - Py_DECREF(POP()); - while (oparg--) { - Py_DECREF(POP()); - } - PUSH(map); - DISPATCH(); - } - - case TARGET(DICT_UPDATE): { - PyObject *update = POP(); - PyObject *dict = PEEK(oparg); - if (PyDict_Update(dict, update) < 0) { - if (_PyErr_ExceptionMatches(tstate, PyExc_AttributeError)) { - _PyErr_Format(tstate, PyExc_TypeError, - "'%.200s' object is not a mapping", - Py_TYPE(update)->tp_name); - } - Py_DECREF(update); - goto error; - } - Py_DECREF(update); - DISPATCH(); - } - - case TARGET(DICT_MERGE): { - PyObject *update = POP(); - PyObject *dict = PEEK(oparg); - - if (_PyDict_MergeEx(dict, update, 2) < 0) { - format_kwargs_error(tstate, PEEK(2 + oparg), update); - Py_DECREF(update); - goto error; - } - Py_DECREF(update); - PREDICT(CALL_FUNCTION_EX); - DISPATCH(); - } - - case TARGET(MAP_ADD): { - PyObject *value = TOP(); - PyObject *key = SECOND(); - PyObject *map; - int err; - STACK_SHRINK(2); - map = PEEK(oparg); /* dict */ - assert(PyDict_CheckExact(map)); - err = PyDict_SetItem(map, key, value); /* map[key] = value */ - Py_DECREF(value); - Py_DECREF(key); - if (err != 0) - goto error; - PREDICT(JUMP_ABSOLUTE); - DISPATCH(); - } - - case TARGET(LOAD_ATTR): { - PyObject *name = GETITEM(names, oparg); - PyObject *owner = TOP(); - - PyTypeObject *type = Py_TYPE(owner); - PyObject *res; - PyObject **dictptr; - PyObject *dict; - _PyOpCodeOpt_LoadAttr *la; - - OPCACHE_STAT_ATTR_TOTAL(); - - OPCACHE_CHECK(); - if (co_opcache != NULL && PyType_HasFeature(type, Py_TPFLAGS_VALID_VERSION_TAG)) - { - if (co_opcache->optimized > 0) { - // Fast path -- cache hit makes LOAD_ATTR ~30% faster. - la = &co_opcache->u.la; - if (la->type == type && la->tp_version_tag == type->tp_version_tag) - { - // Hint >= 0 is a dict index; hint == -1 is a dict miss. - // Hint < -1 is an inverted slot offset: offset is strictly > 0, - // so ~offset is strictly < -1 (assuming 2's complement). - if (la->hint < -1) { - // Even faster path -- slot hint. - Py_ssize_t offset = ~la->hint; - // fprintf(stderr, "Using hint for offset %zd\n", offset); - char *addr = (char *)owner + offset; - res = *(PyObject **)addr; - if (res != NULL) { - Py_INCREF(res); - SET_TOP(res); - Py_DECREF(owner); - DISPATCH(); - } - // Else slot is NULL. Fall through to slow path to raise AttributeError(name). - // Don't DEOPT, since the slot is still there. - } else { - // Fast path for dict. - assert(type->tp_dict != NULL); - assert(type->tp_dictoffset > 0); - - dictptr = (PyObject **) ((char *)owner + type->tp_dictoffset); - dict = *dictptr; - if (dict != NULL && PyDict_CheckExact(dict)) { - Py_ssize_t hint = la->hint; - Py_INCREF(dict); - res = NULL; - assert(!_PyErr_Occurred(tstate)); - la->hint = _PyDict_GetItemHint((PyDictObject*)dict, name, hint, &res); - if (res != NULL) { - assert(la->hint >= 0); - if (la->hint == hint && hint >= 0) { - // Our hint has helped -- cache hit. - OPCACHE_STAT_ATTR_HIT(); - } else { - // The hint we provided didn't work. - // Maybe next time? - OPCACHE_MAYBE_DEOPT_LOAD_ATTR(); - } - - Py_INCREF(res); - SET_TOP(res); - Py_DECREF(owner); - Py_DECREF(dict); - DISPATCH(); - } - else { - _PyErr_Clear(tstate); - // This attribute can be missing sometimes; - // we don't want to optimize this lookup. - OPCACHE_DEOPT_LOAD_ATTR(); - Py_DECREF(dict); - } - } - else { - // There is no dict, or __dict__ doesn't satisfy PyDict_CheckExact. - OPCACHE_DEOPT_LOAD_ATTR(); - } - } - } - else { - // The type of the object has either been updated, - // or is different. Maybe it will stabilize? - OPCACHE_MAYBE_DEOPT_LOAD_ATTR(); - } - OPCACHE_STAT_ATTR_MISS(); - } - - if (co_opcache != NULL && // co_opcache can be NULL after a DEOPT() call. - type->tp_getattro == PyObject_GenericGetAttr) - { - if (type->tp_dict == NULL) { - if (PyType_Ready(type) < 0) { - Py_DECREF(owner); - SET_TOP(NULL); - goto error; - } - } - PyObject *descr = _PyType_Lookup(type, name); - if (descr != NULL) { - // We found an attribute with a data-like descriptor. - PyTypeObject *dtype = Py_TYPE(descr); - if (dtype == &PyMemberDescr_Type) { // It's a slot - PyMemberDescrObject *member = (PyMemberDescrObject *)descr; - struct PyMemberDef *dmem = member->d_member; - if (dmem->type == T_OBJECT_EX) { - Py_ssize_t offset = dmem->offset; - assert(offset > 0); // 0 would be confused with dict hint == -1 (miss). - - if (co_opcache->optimized == 0) { - // First time we optimize this opcode. - OPCACHE_STAT_ATTR_OPT(); - co_opcache->optimized = OPCODE_CACHE_MAX_TRIES; - // fprintf(stderr, "Setting hint for %s, offset %zd\n", dmem->name, offset); - } - - la = &co_opcache->u.la; - la->type = type; - la->tp_version_tag = type->tp_version_tag; - la->hint = ~offset; - - char *addr = (char *)owner + offset; - res = *(PyObject **)addr; - if (res != NULL) { - Py_INCREF(res); - Py_DECREF(owner); - SET_TOP(res); - - DISPATCH(); - } - // Else slot is NULL. Fall through to slow path to raise AttributeError(name). - } - // Else it's a slot of a different type. We don't handle those. - } - // Else it's some other kind of descriptor that we don't handle. - OPCACHE_DEOPT_LOAD_ATTR(); - } - else if (type->tp_dictoffset > 0) { - // We found an instance with a __dict__. - dictptr = (PyObject **) ((char *)owner + type->tp_dictoffset); - dict = *dictptr; - - if (dict != NULL && PyDict_CheckExact(dict)) { - Py_INCREF(dict); - res = NULL; - assert(!_PyErr_Occurred(tstate)); - Py_ssize_t hint = _PyDict_GetItemHint((PyDictObject*)dict, name, -1, &res); - if (res != NULL) { - Py_INCREF(res); - Py_DECREF(dict); - Py_DECREF(owner); - SET_TOP(res); - - if (co_opcache->optimized == 0) { - // First time we optimize this opcode. - OPCACHE_STAT_ATTR_OPT(); - co_opcache->optimized = OPCODE_CACHE_MAX_TRIES; - } - - la = &co_opcache->u.la; - la->type = type; - la->tp_version_tag = type->tp_version_tag; - assert(hint >= 0); - la->hint = hint; - - DISPATCH(); - } - else { - _PyErr_Clear(tstate); - } - Py_DECREF(dict); - } else { - // There is no dict, or __dict__ doesn't satisfy PyDict_CheckExact. - OPCACHE_DEOPT_LOAD_ATTR(); - } - } else { - // The object's class does not have a tp_dictoffset we can use. - OPCACHE_DEOPT_LOAD_ATTR(); - } - } else if (type->tp_getattro != PyObject_GenericGetAttr) { - OPCACHE_DEOPT_LOAD_ATTR(); - } - } - - // Slow path. - res = PyObject_GetAttr(owner, name); - Py_DECREF(owner); - SET_TOP(res); - if (res == NULL) - goto error; - DISPATCH(); - } - - case TARGET(COMPARE_OP): { - assert(oparg <= Py_GE); - PyObject *right = POP(); - PyObject *left = TOP(); - PyObject *res = PyObject_RichCompare(left, right, oparg); - SET_TOP(res); - Py_DECREF(left); - Py_DECREF(right); - if (res == NULL) - goto error; - PREDICT(POP_JUMP_IF_FALSE); - PREDICT(POP_JUMP_IF_TRUE); - DISPATCH(); - } - - case TARGET(IS_OP): { - PyObject *right = POP(); - PyObject *left = TOP(); - int res = Py_Is(left, right) ^ oparg; - PyObject *b = res ? Py_True : Py_False; - Py_INCREF(b); - SET_TOP(b); - Py_DECREF(left); - Py_DECREF(right); - PREDICT(POP_JUMP_IF_FALSE); - PREDICT(POP_JUMP_IF_TRUE); - DISPATCH(); - } - - case TARGET(CONTAINS_OP): { - PyObject *right = POP(); - PyObject *left = POP(); - int res = PySequence_Contains(right, left); - Py_DECREF(left); - Py_DECREF(right); - if (res < 0) { - goto error; - } - PyObject *b = (res^oparg) ? Py_True : Py_False; - Py_INCREF(b); - PUSH(b); - PREDICT(POP_JUMP_IF_FALSE); - PREDICT(POP_JUMP_IF_TRUE); - DISPATCH(); - } - -#define CANNOT_CATCH_MSG "catching classes that do not inherit from "\ - "BaseException is not allowed" - - case TARGET(JUMP_IF_NOT_EXC_MATCH): { - PyObject *right = POP(); - PyObject *left = POP(); - if (PyTuple_Check(right)) { - Py_ssize_t i, length; - length = PyTuple_GET_SIZE(right); - for (i = 0; i < length; i++) { - PyObject *exc = PyTuple_GET_ITEM(right, i); - if (!PyExceptionClass_Check(exc)) { - _PyErr_SetString(tstate, PyExc_TypeError, - CANNOT_CATCH_MSG); - Py_DECREF(left); - Py_DECREF(right); - goto error; - } - } - } - else { - if (!PyExceptionClass_Check(right)) { - _PyErr_SetString(tstate, PyExc_TypeError, - CANNOT_CATCH_MSG); - Py_DECREF(left); - Py_DECREF(right); - goto error; - } - } - int res = PyErr_GivenExceptionMatches(left, right); - Py_DECREF(left); - Py_DECREF(right); - if (res > 0) { - /* Exception matches -- Do nothing */; - } - else if (res == 0) { - JUMPTO(oparg); - } - else { - goto error; - } - DISPATCH(); - } - - case TARGET(IMPORT_NAME): { - PyObject *name = GETITEM(names, oparg); - PyObject *fromlist = POP(); - PyObject *level = TOP(); - PyObject *res; - res = import_name(tstate, f, name, fromlist, level); - Py_DECREF(level); - Py_DECREF(fromlist); - SET_TOP(res); - if (res == NULL) - goto error; - DISPATCH(); - } - - case TARGET(IMPORT_STAR): { - PyObject *from = POP(), *locals; - int err; - if (PyFrame_FastToLocalsWithError(f) < 0) { - Py_DECREF(from); - goto error; - } - - locals = f->f_locals; - if (locals == NULL) { - _PyErr_SetString(tstate, PyExc_SystemError, - "no locals found during 'import *'"); - Py_DECREF(from); - goto error; - } - err = import_all_from(tstate, locals, from); - PyFrame_LocalsToFast(f, 0); - Py_DECREF(from); - if (err != 0) - goto error; - DISPATCH(); - } - - case TARGET(IMPORT_FROM): { - PyObject *name = GETITEM(names, oparg); - PyObject *from = TOP(); - PyObject *res; - res = import_from(tstate, from, name); - PUSH(res); - if (res == NULL) - goto error; - DISPATCH(); - } - - case TARGET(JUMP_FORWARD): { - JUMPBY(oparg); - DISPATCH(); - } - - case TARGET(POP_JUMP_IF_FALSE): { - PREDICTED(POP_JUMP_IF_FALSE); - PyObject *cond = POP(); - int err; - if (Py_IsTrue(cond)) { - Py_DECREF(cond); - DISPATCH(); - } - if (Py_IsFalse(cond)) { - Py_DECREF(cond); - JUMPTO(oparg); - CHECK_EVAL_BREAKER(); - DISPATCH(); - } - err = PyObject_IsTrue(cond); - Py_DECREF(cond); - if (err > 0) - ; - else if (err == 0) { - JUMPTO(oparg); - CHECK_EVAL_BREAKER(); - } - else - goto error; - DISPATCH(); - } - - case TARGET(POP_JUMP_IF_TRUE): { - PREDICTED(POP_JUMP_IF_TRUE); - PyObject *cond = POP(); - int err; - if (Py_IsFalse(cond)) { - Py_DECREF(cond); - DISPATCH(); - } - if (Py_IsTrue(cond)) { - Py_DECREF(cond); - JUMPTO(oparg); - CHECK_EVAL_BREAKER(); - DISPATCH(); - } - err = PyObject_IsTrue(cond); - Py_DECREF(cond); - if (err > 0) { - JUMPTO(oparg); - CHECK_EVAL_BREAKER(); - } - else if (err == 0) - ; - else - goto error; - DISPATCH(); - } - - case TARGET(JUMP_IF_FALSE_OR_POP): { - PyObject *cond = TOP(); - int err; - if (Py_IsTrue(cond)) { - STACK_SHRINK(1); - Py_DECREF(cond); - DISPATCH(); - } - if (Py_IsFalse(cond)) { - JUMPTO(oparg); - DISPATCH(); - } - err = PyObject_IsTrue(cond); - if (err > 0) { - STACK_SHRINK(1); - Py_DECREF(cond); - } - else if (err == 0) - JUMPTO(oparg); - else - goto error; - DISPATCH(); - } - - case TARGET(JUMP_IF_TRUE_OR_POP): { - PyObject *cond = TOP(); - int err; - if (Py_IsFalse(cond)) { - STACK_SHRINK(1); - Py_DECREF(cond); - DISPATCH(); - } - if (Py_IsTrue(cond)) { - JUMPTO(oparg); - DISPATCH(); - } - err = PyObject_IsTrue(cond); - if (err > 0) { - JUMPTO(oparg); - } - else if (err == 0) { - STACK_SHRINK(1); - Py_DECREF(cond); - } - else - goto error; - DISPATCH(); - } - - case TARGET(JUMP_ABSOLUTE): { - PREDICTED(JUMP_ABSOLUTE); - JUMPTO(oparg); - CHECK_EVAL_BREAKER(); - DISPATCH(); - } - - case TARGET(GET_LEN): { - // PUSH(len(TOS)) - Py_ssize_t len_i = PyObject_Length(TOP()); - if (len_i < 0) { - goto error; - } - PyObject *len_o = PyLong_FromSsize_t(len_i); - if (len_o == NULL) { - goto error; - } - PUSH(len_o); - DISPATCH(); - } - - case TARGET(MATCH_CLASS): { - // Pop TOS. On success, set TOS to True and TOS1 to a tuple of - // attributes. On failure, set TOS to False. - PyObject *names = POP(); - PyObject *type = TOP(); - PyObject *subject = SECOND(); - assert(PyTuple_CheckExact(names)); - PyObject *attrs = match_class(tstate, subject, type, oparg, names); - Py_DECREF(names); - if (attrs) { - // Success! - assert(PyTuple_CheckExact(attrs)); - Py_DECREF(subject); - SET_SECOND(attrs); - } - else if (_PyErr_Occurred(tstate)) { - goto error; - } - Py_DECREF(type); - SET_TOP(PyBool_FromLong(!!attrs)); - DISPATCH(); - } - - case TARGET(MATCH_MAPPING): { - PyObject *subject = TOP(); - int match = Py_TYPE(subject)->tp_flags & Py_TPFLAGS_MAPPING; - PyObject *res = match ? Py_True : Py_False; - Py_INCREF(res); - PUSH(res); - DISPATCH(); - } - - case TARGET(MATCH_SEQUENCE): { - PyObject *subject = TOP(); - int match = Py_TYPE(subject)->tp_flags & Py_TPFLAGS_SEQUENCE; - PyObject *res = match ? Py_True : Py_False; - Py_INCREF(res); - PUSH(res); - DISPATCH(); - } - - case TARGET(MATCH_KEYS): { - // On successful match for all keys, PUSH(values) and PUSH(True). - // Otherwise, PUSH(None) and PUSH(False). - PyObject *keys = TOP(); - PyObject *subject = SECOND(); - PyObject *values_or_none = match_keys(tstate, subject, keys); - if (values_or_none == NULL) { - goto error; - } - PUSH(values_or_none); - if (Py_IsNone(values_or_none)) { - Py_INCREF(Py_False); - PUSH(Py_False); - DISPATCH(); - } - assert(PyTuple_CheckExact(values_or_none)); - Py_INCREF(Py_True); - PUSH(Py_True); - DISPATCH(); - } - - case TARGET(COPY_DICT_WITHOUT_KEYS): { - // rest = dict(TOS1) - // for key in TOS: - // del rest[key] - // SET_TOP(rest) - PyObject *keys = TOP(); - PyObject *subject = SECOND(); - PyObject *rest = PyDict_New(); - if (rest == NULL || PyDict_Update(rest, subject)) { - Py_XDECREF(rest); - goto error; - } - // This may seem a bit inefficient, but keys is rarely big enough to - // actually impact runtime. - assert(PyTuple_CheckExact(keys)); - for (Py_ssize_t i = 0; i < PyTuple_GET_SIZE(keys); i++) { - if (PyDict_DelItem(rest, PyTuple_GET_ITEM(keys, i))) { - Py_DECREF(rest); - goto error; - } - } - Py_DECREF(keys); - SET_TOP(rest); - DISPATCH(); - } - - case TARGET(GET_ITER): { - /* before: [obj]; after [getiter(obj)] */ - PyObject *iterable = TOP(); - PyObject *iter = PyObject_GetIter(iterable); - Py_DECREF(iterable); - SET_TOP(iter); - if (iter == NULL) - goto error; - PREDICT(FOR_ITER); - PREDICT(CALL_FUNCTION); - DISPATCH(); - } - - case TARGET(GET_YIELD_FROM_ITER): { - /* before: [obj]; after [getiter(obj)] */ - PyObject *iterable = TOP(); - PyObject *iter; - if (PyCoro_CheckExact(iterable)) { - /* `iterable` is a coroutine */ - if (!(co->co_flags & (CO_COROUTINE | CO_ITERABLE_COROUTINE))) { - /* and it is used in a 'yield from' expression of a - regular generator. */ - Py_DECREF(iterable); - SET_TOP(NULL); - _PyErr_SetString(tstate, PyExc_TypeError, - "cannot 'yield from' a coroutine object " - "in a non-coroutine generator"); - goto error; - } - } - else if (!PyGen_CheckExact(iterable)) { - /* `iterable` is not a generator. */ - iter = PyObject_GetIter(iterable); - Py_DECREF(iterable); - SET_TOP(iter); - if (iter == NULL) - goto error; - } - PREDICT(LOAD_CONST); - DISPATCH(); - } - - case TARGET(FOR_ITER): { - PREDICTED(FOR_ITER); - /* before: [iter]; after: [iter, iter()] *or* [] */ - PyObject *iter = TOP(); - PyObject *next = (*Py_TYPE(iter)->tp_iternext)(iter); - if (next != NULL) { - PUSH(next); - PREDICT(STORE_FAST); - PREDICT(UNPACK_SEQUENCE); - DISPATCH(); - } - if (_PyErr_Occurred(tstate)) { - if (!_PyErr_ExceptionMatches(tstate, PyExc_StopIteration)) { - goto error; - } - else if (tstate->c_tracefunc != NULL) { - call_exc_trace(tstate->c_tracefunc, tstate->c_traceobj, tstate, f, &trace_info); - } - _PyErr_Clear(tstate); - } - /* iterator ended normally */ - STACK_SHRINK(1); - Py_DECREF(iter); - JUMPBY(oparg); - DISPATCH(); - } - - case TARGET(SETUP_FINALLY): { - PyFrame_BlockSetup(f, SETUP_FINALLY, INSTR_OFFSET() + oparg, - STACK_LEVEL()); - DISPATCH(); - } - - case TARGET(BEFORE_ASYNC_WITH): { - _Py_IDENTIFIER(__aenter__); - _Py_IDENTIFIER(__aexit__); - PyObject *mgr = TOP(); - PyObject *enter = special_lookup(tstate, mgr, &PyId___aenter__); - PyObject *res; - if (enter == NULL) { - goto error; - } - PyObject *exit = special_lookup(tstate, mgr, &PyId___aexit__); - if (exit == NULL) { - Py_DECREF(enter); - goto error; - } - SET_TOP(exit); - Py_DECREF(mgr); - res = _PyObject_CallNoArg(enter); - Py_DECREF(enter); - if (res == NULL) - goto error; - PUSH(res); - PREDICT(GET_AWAITABLE); - DISPATCH(); - } - - case TARGET(SETUP_ASYNC_WITH): { - PyObject *res = POP(); - /* Setup the finally block before pushing the result - of __aenter__ on the stack. */ - PyFrame_BlockSetup(f, SETUP_FINALLY, INSTR_OFFSET() + oparg, - STACK_LEVEL()); - PUSH(res); - DISPATCH(); - } - - case TARGET(SETUP_WITH): { - _Py_IDENTIFIER(__enter__); - _Py_IDENTIFIER(__exit__); - PyObject *mgr = TOP(); - PyObject *enter = special_lookup(tstate, mgr, &PyId___enter__); - PyObject *res; - if (enter == NULL) { - goto error; - } - PyObject *exit = special_lookup(tstate, mgr, &PyId___exit__); - if (exit == NULL) { - Py_DECREF(enter); - goto error; - } - SET_TOP(exit); - Py_DECREF(mgr); - res = _PyObject_CallNoArg(enter); - Py_DECREF(enter); - if (res == NULL) - goto error; - /* Setup the finally block before pushing the result - of __enter__ on the stack. */ - PyFrame_BlockSetup(f, SETUP_FINALLY, INSTR_OFFSET() + oparg, - STACK_LEVEL()); - - PUSH(res); - DISPATCH(); - } - - case TARGET(WITH_EXCEPT_START): { - /* At the top of the stack are 7 values: - - (TOP, SECOND, THIRD) = exc_info() - - (FOURTH, FIFTH, SIXTH) = previous exception for EXCEPT_HANDLER - - SEVENTH: the context.__exit__ bound method - We call SEVENTH(TOP, SECOND, THIRD). - Then we push again the TOP exception and the __exit__ - return value. - */ - PyObject *exit_func; - PyObject *exc, *val, *tb, *res; - - exc = TOP(); - val = SECOND(); - tb = THIRD(); - assert(!Py_IsNone(exc)); - assert(!PyLong_Check(exc)); - exit_func = PEEK(7); - PyObject *stack[4] = {NULL, exc, val, tb}; - res = PyObject_Vectorcall(exit_func, stack + 1, - 3 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); - if (res == NULL) - goto error; - - PUSH(res); - DISPATCH(); - } - - case TARGET(LOAD_METHOD): { - /* Designed to work in tandem with CALL_METHOD. */ - PyObject *name = GETITEM(names, oparg); - PyObject *obj = TOP(); - PyObject *meth = NULL; - - int meth_found = _PyObject_GetMethod(obj, name, &meth); - - if (meth == NULL) { - /* Most likely attribute wasn't found. */ - goto error; - } - - if (meth_found) { - /* We can bypass temporary bound method object. - meth is unbound method and obj is self. - - meth | self | arg1 | ... | argN - */ - SET_TOP(meth); - PUSH(obj); // self - } - else { - /* meth is not an unbound method (but a regular attr, or - something was returned by a descriptor protocol). Set - the second element of the stack to NULL, to signal - CALL_METHOD that it's not a method call. - - NULL | meth | arg1 | ... | argN - */ - SET_TOP(NULL); - Py_DECREF(obj); - PUSH(meth); - } - DISPATCH(); - } - - case TARGET(CALL_METHOD): { - /* Designed to work in tamdem with LOAD_METHOD. */ - PyObject **sp, *res, *meth; - - sp = stack_pointer; - - meth = PEEK(oparg + 2); - if (meth == NULL) { - /* `meth` is NULL when LOAD_METHOD thinks that it's not - a method call. - - Stack layout: - - ... | NULL | callable | arg1 | ... | argN - ^- TOP() - ^- (-oparg) - ^- (-oparg-1) - ^- (-oparg-2) - - `callable` will be POPed by call_function. - NULL will will be POPed manually later. - */ - res = call_function(tstate, &trace_info, &sp, oparg, NULL); - stack_pointer = sp; - (void)POP(); /* POP the NULL. */ - } - else { - /* This is a method call. Stack layout: - - ... | method | self | arg1 | ... | argN - ^- TOP() - ^- (-oparg) - ^- (-oparg-1) - ^- (-oparg-2) - - `self` and `method` will be POPed by call_function. - We'll be passing `oparg + 1` to call_function, to - make it accept the `self` as a first argument. - */ - res = call_function(tstate, &trace_info, &sp, oparg + 1, NULL); - stack_pointer = sp; - } - - PUSH(res); - if (res == NULL) - goto error; - CHECK_EVAL_BREAKER(); - DISPATCH(); - } - - case TARGET(CALL_FUNCTION): { - PREDICTED(CALL_FUNCTION); - PyObject **sp, *res; - sp = stack_pointer; - res = call_function(tstate, &trace_info, &sp, oparg, NULL); - stack_pointer = sp; - PUSH(res); - if (res == NULL) { - goto error; - } - CHECK_EVAL_BREAKER(); - DISPATCH(); - } - - case TARGET(CALL_FUNCTION_KW): { - PyObject **sp, *res, *names; - - names = POP(); - assert(PyTuple_Check(names)); - assert(PyTuple_GET_SIZE(names) <= oparg); - /* We assume without checking that names contains only strings */ - sp = stack_pointer; - res = call_function(tstate, &trace_info, &sp, oparg, names); - stack_pointer = sp; - PUSH(res); - Py_DECREF(names); - - if (res == NULL) { - goto error; - } - CHECK_EVAL_BREAKER(); - DISPATCH(); - } - - case TARGET(CALL_FUNCTION_EX): { - PREDICTED(CALL_FUNCTION_EX); - PyObject *func, *callargs, *kwargs = NULL, *result; - if (oparg & 0x01) { - kwargs = POP(); - if (!PyDict_CheckExact(kwargs)) { - PyObject *d = PyDict_New(); - if (d == NULL) - goto error; - if (_PyDict_MergeEx(d, kwargs, 2) < 0) { - Py_DECREF(d); - format_kwargs_error(tstate, SECOND(), kwargs); - Py_DECREF(kwargs); - goto error; - } - Py_DECREF(kwargs); - kwargs = d; - } - assert(PyDict_CheckExact(kwargs)); - } - callargs = POP(); - func = TOP(); - if (!PyTuple_CheckExact(callargs)) { - if (check_args_iterable(tstate, func, callargs) < 0) { - Py_DECREF(callargs); - goto error; - } - Py_SETREF(callargs, PySequence_Tuple(callargs)); - if (callargs == NULL) { - goto error; - } - } - assert(PyTuple_CheckExact(callargs)); - - result = do_call_core(tstate, &trace_info, func, callargs, kwargs); - Py_DECREF(func); - Py_DECREF(callargs); - Py_XDECREF(kwargs); - - SET_TOP(result); - if (result == NULL) { - goto error; - } - CHECK_EVAL_BREAKER(); - DISPATCH(); - } - - case TARGET(MAKE_FUNCTION): { - PyObject *qualname = POP(); - PyObject *codeobj = POP(); - PyFunctionObject *func = (PyFunctionObject *) - PyFunction_NewWithQualName(codeobj, f->f_globals, qualname); - - Py_DECREF(codeobj); - Py_DECREF(qualname); - if (func == NULL) { - goto error; - } - - if (oparg & 0x08) { - assert(PyTuple_CheckExact(TOP())); - func->func_closure = POP(); - } - if (oparg & 0x04) { - assert(PyTuple_CheckExact(TOP())); - func->func_annotations = POP(); - } - if (oparg & 0x02) { - assert(PyDict_CheckExact(TOP())); - func->func_kwdefaults = POP(); - } - if (oparg & 0x01) { - assert(PyTuple_CheckExact(TOP())); - func->func_defaults = POP(); - } - - PUSH((PyObject *)func); - DISPATCH(); - } - - case TARGET(BUILD_SLICE): { - PyObject *start, *stop, *step, *slice; - if (oparg == 3) - step = POP(); - else - step = NULL; - stop = POP(); - start = TOP(); - slice = PySlice_New(start, stop, step); - Py_DECREF(start); - Py_DECREF(stop); - Py_XDECREF(step); - SET_TOP(slice); - if (slice == NULL) - goto error; - DISPATCH(); - } - - case TARGET(FORMAT_VALUE): { - /* Handles f-string value formatting. */ - PyObject *result; - PyObject *fmt_spec; - PyObject *value; - PyObject *(*conv_fn)(PyObject *); - int which_conversion = oparg & FVC_MASK; - int have_fmt_spec = (oparg & FVS_MASK) == FVS_HAVE_SPEC; - - fmt_spec = have_fmt_spec ? POP() : NULL; - value = POP(); - - /* See if any conversion is specified. */ - switch (which_conversion) { - case FVC_NONE: conv_fn = NULL; break; - case FVC_STR: conv_fn = PyObject_Str; break; - case FVC_REPR: conv_fn = PyObject_Repr; break; - case FVC_ASCII: conv_fn = PyObject_ASCII; break; - default: - _PyErr_Format(tstate, PyExc_SystemError, - "unexpected conversion flag %d", - which_conversion); - goto error; - } - - /* If there's a conversion function, call it and replace - value with that result. Otherwise, just use value, - without conversion. */ - if (conv_fn != NULL) { - result = conv_fn(value); - Py_DECREF(value); - if (result == NULL) { - Py_XDECREF(fmt_spec); - goto error; - } - value = result; - } - - /* If value is a unicode object, and there's no fmt_spec, - then we know the result of format(value) is value - itself. In that case, skip calling format(). I plan to - move this optimization in to PyObject_Format() - itself. */ - if (PyUnicode_CheckExact(value) && fmt_spec == NULL) { - /* Do nothing, just transfer ownership to result. */ - result = value; - } else { - /* Actually call format(). */ - result = PyObject_Format(value, fmt_spec); - Py_DECREF(value); - Py_XDECREF(fmt_spec); - if (result == NULL) { - goto error; - } - } - - PUSH(result); - DISPATCH(); - } - - case TARGET(ROT_N): { - PyObject *top = TOP(); - memmove(&PEEK(oparg - 1), &PEEK(oparg), - sizeof(PyObject*) * (oparg - 1)); - PEEK(oparg) = top; - DISPATCH(); - } - - case TARGET(EXTENDED_ARG): { - int oldoparg = oparg; - NEXTOPARG(); - oparg |= oldoparg << 8; - goto dispatch_opcode; - } - - -#if USE_COMPUTED_GOTOS - _unknown_opcode: -#endif - default: - fprintf(stderr, - "XXX lineno: %d, opcode: %d\n", - PyFrame_GetLineNumber(f), - opcode); - _PyErr_SetString(tstate, PyExc_SystemError, "unknown opcode"); - goto error; - - } /* switch */ - - /* This should never be reached. Every opcode should end with DISPATCH() - or goto error. */ - Py_UNREACHABLE(); - -error: - /* Double-check exception status. */ -#ifdef NDEBUG - if (!_PyErr_Occurred(tstate)) { - _PyErr_SetString(tstate, PyExc_SystemError, - "error return without exception set"); - } -#else - assert(_PyErr_Occurred(tstate)); -#endif - - /* Log traceback info. */ - PyTraceBack_Here(f); - - if (tstate->c_tracefunc != NULL) { - /* Make sure state is set to FRAME_EXECUTING for tracing */ - assert(f->f_state == FRAME_EXECUTING); - f->f_state = FRAME_UNWINDING; - call_exc_trace(tstate->c_tracefunc, tstate->c_traceobj, - tstate, f, &trace_info); - } -exception_unwind: - f->f_state = FRAME_UNWINDING; - /* Unwind stacks if an exception occurred */ - while (f->f_iblock > 0) { - /* Pop the current block. */ - PyTryBlock *b = &f->f_blockstack[--f->f_iblock]; - - if (b->b_type == EXCEPT_HANDLER) { - UNWIND_EXCEPT_HANDLER(b); - continue; - } - UNWIND_BLOCK(b); - if (b->b_type == SETUP_FINALLY) { - PyObject *exc, *val, *tb; - int handler = b->b_handler; - _PyErr_StackItem *exc_info = tstate->exc_info; - /* Beware, this invalidates all b->b_* fields */ - PyFrame_BlockSetup(f, EXCEPT_HANDLER, f->f_lasti, STACK_LEVEL()); - PUSH(exc_info->exc_traceback); - PUSH(exc_info->exc_value); - if (exc_info->exc_type != NULL) { - PUSH(exc_info->exc_type); - } - else { - Py_INCREF(Py_None); - PUSH(Py_None); - } - _PyErr_Fetch(tstate, &exc, &val, &tb); - /* Make the raw exception data - available to the handler, - so a program can emulate the - Python main loop. */ - _PyErr_NormalizeException(tstate, &exc, &val, &tb); - if (tb != NULL) - PyException_SetTraceback(val, tb); - else - PyException_SetTraceback(val, Py_None); - Py_INCREF(exc); - exc_info->exc_type = exc; - Py_INCREF(val); - exc_info->exc_value = val; - exc_info->exc_traceback = tb; - if (tb == NULL) - tb = Py_None; - Py_INCREF(tb); - PUSH(tb); - PUSH(val); - PUSH(exc); - JUMPTO(handler); - /* Resume normal execution */ - f->f_state = FRAME_EXECUTING; - goto main_loop; - } - } /* unwind stack */ - - /* End the loop as we still have an error */ - break; - } /* main loop */ - - assert(retval == NULL); - assert(_PyErr_Occurred(tstate)); - - /* Pop remaining stack entries. */ - while (!EMPTY()) { - PyObject *o = POP(); - Py_XDECREF(o); - } - f->f_stackdepth = 0; - f->f_state = FRAME_RAISED; -exiting: - if (trace_info.cframe.use_tracing) { - if (tstate->c_tracefunc) { - if (call_trace_protected(tstate->c_tracefunc, tstate->c_traceobj, - tstate, f, &trace_info, PyTrace_RETURN, retval)) { - Py_CLEAR(retval); - } - } - if (tstate->c_profilefunc) { - if (call_trace_protected(tstate->c_profilefunc, tstate->c_profileobj, - tstate, f, &trace_info, PyTrace_RETURN, retval)) { - Py_CLEAR(retval); - } - } - } - - /* pop frame */ -exit_eval_frame: - /* Restore previous cframe */ - tstate->cframe = trace_info.cframe.previous; - tstate->cframe->use_tracing = trace_info.cframe.use_tracing; - - if (PyDTrace_FUNCTION_RETURN_ENABLED()) - dtrace_function_return(f); - _Py_LeaveRecursiveCall(tstate); - tstate->frame = f->f_back; - - return _Py_CheckFunctionResult(tstate, NULL, retval, __func__); -} - -static void -format_missing(PyThreadState *tstate, const char *kind, - PyCodeObject *co, PyObject *names, PyObject *qualname) -{ - int err; - Py_ssize_t len = PyList_GET_SIZE(names); - PyObject *name_str, *comma, *tail, *tmp; - - assert(PyList_CheckExact(names)); - assert(len >= 1); - /* Deal with the joys of natural language. */ - switch (len) { - case 1: - name_str = PyList_GET_ITEM(names, 0); - Py_INCREF(name_str); - break; - case 2: - name_str = PyUnicode_FromFormat("%U and %U", - PyList_GET_ITEM(names, len - 2), - PyList_GET_ITEM(names, len - 1)); - break; - default: - tail = PyUnicode_FromFormat(", %U, and %U", - PyList_GET_ITEM(names, len - 2), - PyList_GET_ITEM(names, len - 1)); - if (tail == NULL) - return; - /* Chop off the last two objects in the list. This shouldn't actually - fail, but we can't be too careful. */ - err = PyList_SetSlice(names, len - 2, len, NULL); - if (err == -1) { - Py_DECREF(tail); - return; - } - /* Stitch everything up into a nice comma-separated list. */ - comma = PyUnicode_FromString(", "); - if (comma == NULL) { - Py_DECREF(tail); - return; - } - tmp = PyUnicode_Join(comma, names); - Py_DECREF(comma); - if (tmp == NULL) { - Py_DECREF(tail); - return; - } - name_str = PyUnicode_Concat(tmp, tail); - Py_DECREF(tmp); - Py_DECREF(tail); - break; - } - if (name_str == NULL) - return; - _PyErr_Format(tstate, PyExc_TypeError, - "%U() missing %i required %s argument%s: %U", - qualname, - len, - kind, - len == 1 ? "" : "s", - name_str); - Py_DECREF(name_str); -} - -static void -missing_arguments(PyThreadState *tstate, PyCodeObject *co, - Py_ssize_t missing, Py_ssize_t defcount, - PyObject **fastlocals, PyObject *qualname) -{ - Py_ssize_t i, j = 0; - Py_ssize_t start, end; - int positional = (defcount != -1); - const char *kind = positional ? "positional" : "keyword-only"; - PyObject *missing_names; - - /* Compute the names of the arguments that are missing. */ - missing_names = PyList_New(missing); - if (missing_names == NULL) - return; - if (positional) { - start = 0; - end = co->co_argcount - defcount; - } - else { - start = co->co_argcount; - end = start + co->co_kwonlyargcount; - } - for (i = start; i < end; i++) { - if (GETLOCAL(i) == NULL) { - PyObject *raw = PyTuple_GET_ITEM(co->co_varnames, i); - PyObject *name = PyObject_Repr(raw); - if (name == NULL) { - Py_DECREF(missing_names); - return; - } - PyList_SET_ITEM(missing_names, j++, name); - } - } - assert(j == missing); - format_missing(tstate, kind, co, missing_names, qualname); - Py_DECREF(missing_names); -} - -static void -too_many_positional(PyThreadState *tstate, PyCodeObject *co, - Py_ssize_t given, PyObject *defaults, - PyObject **fastlocals, PyObject *qualname) -{ - int plural; - Py_ssize_t kwonly_given = 0; - Py_ssize_t i; - PyObject *sig, *kwonly_sig; - Py_ssize_t co_argcount = co->co_argcount; - - assert((co->co_flags & CO_VARARGS) == 0); - /* Count missing keyword-only args. */ - for (i = co_argcount; i < co_argcount + co->co_kwonlyargcount; i++) { - if (GETLOCAL(i) != NULL) { - kwonly_given++; - } - } - Py_ssize_t defcount = defaults == NULL ? 0 : PyTuple_GET_SIZE(defaults); - if (defcount) { - Py_ssize_t atleast = co_argcount - defcount; - plural = 1; - sig = PyUnicode_FromFormat("from %zd to %zd", atleast, co_argcount); - } - else { - plural = (co_argcount != 1); - sig = PyUnicode_FromFormat("%zd", co_argcount); - } - if (sig == NULL) - return; - if (kwonly_given) { - const char *format = " positional argument%s (and %zd keyword-only argument%s)"; - kwonly_sig = PyUnicode_FromFormat(format, - given != 1 ? "s" : "", - kwonly_given, - kwonly_given != 1 ? "s" : ""); - if (kwonly_sig == NULL) { - Py_DECREF(sig); - return; - } - } - else { - /* This will not fail. */ - kwonly_sig = PyUnicode_FromString(""); - assert(kwonly_sig != NULL); - } - _PyErr_Format(tstate, PyExc_TypeError, - "%U() takes %U positional argument%s but %zd%U %s given", - qualname, - sig, - plural ? "s" : "", - given, - kwonly_sig, - given == 1 && !kwonly_given ? "was" : "were"); - Py_DECREF(sig); - Py_DECREF(kwonly_sig); -} - -static int -positional_only_passed_as_keyword(PyThreadState *tstate, PyCodeObject *co, - Py_ssize_t kwcount, PyObject* kwnames, - PyObject *qualname) -{ - int posonly_conflicts = 0; - PyObject* posonly_names = PyList_New(0); - - for(int k=0; k < co->co_posonlyargcount; k++){ - PyObject* posonly_name = PyTuple_GET_ITEM(co->co_varnames, k); - - for (int k2=0; k2<kwcount; k2++){ - /* Compare the pointers first and fallback to PyObject_RichCompareBool*/ - PyObject* kwname = PyTuple_GET_ITEM(kwnames, k2); - if (kwname == posonly_name){ - if(PyList_Append(posonly_names, kwname) != 0) { - goto fail; - } - posonly_conflicts++; - continue; - } - - int cmp = PyObject_RichCompareBool(posonly_name, kwname, Py_EQ); - - if ( cmp > 0) { - if(PyList_Append(posonly_names, kwname) != 0) { - goto fail; - } - posonly_conflicts++; - } else if (cmp < 0) { - goto fail; - } - - } - } - if (posonly_conflicts) { - PyObject* comma = PyUnicode_FromString(", "); - if (comma == NULL) { - goto fail; - } - PyObject* error_names = PyUnicode_Join(comma, posonly_names); - Py_DECREF(comma); - if (error_names == NULL) { - goto fail; - } - _PyErr_Format(tstate, PyExc_TypeError, - "%U() got some positional-only arguments passed" - " as keyword arguments: '%U'", - qualname, error_names); - Py_DECREF(error_names); - goto fail; - } - - Py_DECREF(posonly_names); - return 0; - -fail: - Py_XDECREF(posonly_names); - return 1; - -} - - -PyFrameObject * -_PyEval_MakeFrameVector(PyThreadState *tstate, - PyFrameConstructor *con, PyObject *locals, - PyObject *const *args, Py_ssize_t argcount, - PyObject *kwnames) -{ - assert(is_tstate_valid(tstate)); - - PyCodeObject *co = (PyCodeObject*)con->fc_code; - assert(con->fc_defaults == NULL || PyTuple_CheckExact(con->fc_defaults)); - const Py_ssize_t total_args = co->co_argcount + co->co_kwonlyargcount; - - /* Create the frame */ - PyFrameObject *f = _PyFrame_New_NoTrack(tstate, con, locals); - if (f == NULL) { - return NULL; - } - PyObject **fastlocals = f->f_localsplus; - PyObject **freevars = f->f_localsplus + co->co_nlocals; - - /* Create a dictionary for keyword parameters (**kwags) */ - PyObject *kwdict; - Py_ssize_t i; - if (co->co_flags & CO_VARKEYWORDS) { - kwdict = PyDict_New(); - if (kwdict == NULL) - goto fail; - i = total_args; - if (co->co_flags & CO_VARARGS) { - i++; - } - SETLOCAL(i, kwdict); - } - else { - kwdict = NULL; - } - - /* Copy all positional arguments into local variables */ - Py_ssize_t j, n; - if (argcount > co->co_argcount) { - n = co->co_argcount; - } - else { - n = argcount; - } - for (j = 0; j < n; j++) { - PyObject *x = args[j]; - Py_INCREF(x); - SETLOCAL(j, x); - } - - /* Pack other positional arguments into the *args argument */ - if (co->co_flags & CO_VARARGS) { - PyObject *u = _PyTuple_FromArray(args + n, argcount - n); - if (u == NULL) { - goto fail; - } - SETLOCAL(total_args, u); - } - - /* Handle keyword arguments */ - if (kwnames != NULL) { - Py_ssize_t kwcount = PyTuple_GET_SIZE(kwnames); - for (i = 0; i < kwcount; i++) { - PyObject **co_varnames; - PyObject *keyword = PyTuple_GET_ITEM(kwnames, i); - PyObject *value = args[i+argcount]; - Py_ssize_t j; - - if (keyword == NULL || !PyUnicode_Check(keyword)) { - _PyErr_Format(tstate, PyExc_TypeError, - "%U() keywords must be strings", - con->fc_qualname); - goto fail; - } - - /* Speed hack: do raw pointer compares. As names are - normally interned this should almost always hit. */ - co_varnames = ((PyTupleObject *)(co->co_varnames))->ob_item; - for (j = co->co_posonlyargcount; j < total_args; j++) { - PyObject *varname = co_varnames[j]; - if (varname == keyword) { - goto kw_found; - } - } - - /* Slow fallback, just in case */ - for (j = co->co_posonlyargcount; j < total_args; j++) { - PyObject *varname = co_varnames[j]; - int cmp = PyObject_RichCompareBool( keyword, varname, Py_EQ); - if (cmp > 0) { - goto kw_found; - } - else if (cmp < 0) { - goto fail; - } - } - - assert(j >= total_args); - if (kwdict == NULL) { - - if (co->co_posonlyargcount - && positional_only_passed_as_keyword(tstate, co, - kwcount, kwnames, - con->fc_qualname)) - { - goto fail; - } - - _PyErr_Format(tstate, PyExc_TypeError, - "%U() got an unexpected keyword argument '%S'", - con->fc_qualname, keyword); - goto fail; - } - - if (PyDict_SetItem(kwdict, keyword, value) == -1) { - goto fail; - } - continue; - - kw_found: - if (GETLOCAL(j) != NULL) { - _PyErr_Format(tstate, PyExc_TypeError, - "%U() got multiple values for argument '%S'", - con->fc_qualname, keyword); - goto fail; - } - Py_INCREF(value); - SETLOCAL(j, value); - } - } - - /* Check the number of positional arguments */ - if ((argcount > co->co_argcount) && !(co->co_flags & CO_VARARGS)) { - too_many_positional(tstate, co, argcount, con->fc_defaults, fastlocals, - con->fc_qualname); - goto fail; - } - - /* Add missing positional arguments (copy default values from defs) */ - if (argcount < co->co_argcount) { - Py_ssize_t defcount = con->fc_defaults == NULL ? 0 : PyTuple_GET_SIZE(con->fc_defaults); - Py_ssize_t m = co->co_argcount - defcount; - Py_ssize_t missing = 0; - for (i = argcount; i < m; i++) { - if (GETLOCAL(i) == NULL) { - missing++; - } - } - if (missing) { - missing_arguments(tstate, co, missing, defcount, fastlocals, - con->fc_qualname); - goto fail; - } - if (n > m) - i = n - m; - else - i = 0; - if (defcount) { - PyObject **defs = &PyTuple_GET_ITEM(con->fc_defaults, 0); - for (; i < defcount; i++) { - if (GETLOCAL(m+i) == NULL) { - PyObject *def = defs[i]; - Py_INCREF(def); - SETLOCAL(m+i, def); - } - } - } - } - - /* Add missing keyword arguments (copy default values from kwdefs) */ - if (co->co_kwonlyargcount > 0) { - Py_ssize_t missing = 0; - for (i = co->co_argcount; i < total_args; i++) { - if (GETLOCAL(i) != NULL) - continue; - PyObject *varname = PyTuple_GET_ITEM(co->co_varnames, i); - if (con->fc_kwdefaults != NULL) { - PyObject *def = PyDict_GetItemWithError(con->fc_kwdefaults, varname); - if (def) { - Py_INCREF(def); - SETLOCAL(i, def); - continue; - } - else if (_PyErr_Occurred(tstate)) { - goto fail; - } - } - missing++; - } - if (missing) { - missing_arguments(tstate, co, missing, -1, fastlocals, - con->fc_qualname); - goto fail; - } - } - - /* Allocate and initialize storage for cell vars, and copy free - vars into frame. */ - for (i = 0; i < PyTuple_GET_SIZE(co->co_cellvars); ++i) { - PyObject *c; - Py_ssize_t arg; - /* Possibly account for the cell variable being an argument. */ - if (co->co_cell2arg != NULL && - (arg = co->co_cell2arg[i]) != CO_CELL_NOT_AN_ARG) { - c = PyCell_New(GETLOCAL(arg)); - /* Clear the local copy. */ - SETLOCAL(arg, NULL); - } - else { - c = PyCell_New(NULL); - } - if (c == NULL) - goto fail; - SETLOCAL(co->co_nlocals + i, c); - } - - /* Copy closure variables to free variables */ - for (i = 0; i < PyTuple_GET_SIZE(co->co_freevars); ++i) { - PyObject *o = PyTuple_GET_ITEM(con->fc_closure, i); - Py_INCREF(o); - freevars[PyTuple_GET_SIZE(co->co_cellvars) + i] = o; - } - - return f; - -fail: /* Jump here from prelude on failure */ - - /* decref'ing the frame can cause __del__ methods to get invoked, - which can call back into Python. While we're done with the - current Python frame (f), the associated C stack is still in use, - so recursion_depth must be boosted for the duration. - */ - if (Py_REFCNT(f) > 1) { - Py_DECREF(f); - _PyObject_GC_TRACK(f); - } - else { - ++tstate->recursion_depth; - Py_DECREF(f); - --tstate->recursion_depth; - } - return NULL; -} - -static PyObject * -make_coro(PyFrameConstructor *con, PyFrameObject *f) -{ - assert (((PyCodeObject *)con->fc_code)->co_flags & (CO_GENERATOR | CO_COROUTINE | CO_ASYNC_GENERATOR)); - PyObject *gen; - int is_coro = ((PyCodeObject *)con->fc_code)->co_flags & CO_COROUTINE; - - /* Don't need to keep the reference to f_back, it will be set - * when the generator is resumed. */ - Py_CLEAR(f->f_back); - - /* Create a new generator that owns the ready to run frame - * and return that as the value. */ - if (is_coro) { - gen = PyCoro_New(f, con->fc_name, con->fc_qualname); - } else if (((PyCodeObject *)con->fc_code)->co_flags & CO_ASYNC_GENERATOR) { - gen = PyAsyncGen_New(f, con->fc_name, con->fc_qualname); - } else { - gen = PyGen_NewWithQualName(f, con->fc_name, con->fc_qualname); - } - if (gen == NULL) { - return NULL; - } - - _PyObject_GC_TRACK(f); - - return gen; -} - -PyObject * -_PyEval_Vector(PyThreadState *tstate, PyFrameConstructor *con, - PyObject *locals, - PyObject* const* args, size_t argcount, - PyObject *kwnames) -{ - PyFrameObject *f = _PyEval_MakeFrameVector( - tstate, con, locals, args, argcount, kwnames); - if (f == NULL) { - return NULL; - } - if (((PyCodeObject *)con->fc_code)->co_flags & (CO_GENERATOR | CO_COROUTINE | CO_ASYNC_GENERATOR)) { - return make_coro(con, f); - } - PyObject *retval = _PyEval_EvalFrame(tstate, f, 0); - - /* decref'ing the frame can cause __del__ methods to get invoked, - which can call back into Python. While we're done with the - current Python frame (f), the associated C stack is still in use, - so recursion_depth must be boosted for the duration. - */ - if (Py_REFCNT(f) > 1) { - Py_DECREF(f); - _PyObject_GC_TRACK(f); - } - else { - ++tstate->recursion_depth; - Py_DECREF(f); - --tstate->recursion_depth; - } - return retval; -} - -/* Legacy API */ -PyObject * -PyEval_EvalCodeEx(PyObject *_co, PyObject *globals, PyObject *locals, - PyObject *const *args, int argcount, - PyObject *const *kws, int kwcount, - PyObject *const *defs, int defcount, - PyObject *kwdefs, PyObject *closure) -{ - PyThreadState *tstate = _PyThreadState_GET(); - PyObject *res = NULL; - PyObject *defaults = _PyTuple_FromArray(defs, defcount); - if (defaults == NULL) { - return NULL; - } - PyObject *builtins = _PyEval_BuiltinsFromGlobals(tstate, globals); // borrowed ref - if (builtins == NULL) { - Py_DECREF(defaults); - return NULL; - } - if (locals == NULL) { - locals = globals; - } - PyObject *kwnames = NULL; - PyObject *const *allargs; - PyObject **newargs = NULL; - if (kwcount == 0) { - allargs = args; - } - else { - kwnames = PyTuple_New(kwcount); - if (kwnames == NULL) { - goto fail; - } - newargs = PyMem_Malloc(sizeof(PyObject *)*(kwcount+argcount)); - if (newargs == NULL) { - goto fail; - } - for (int i = 0; i < argcount; i++) { - newargs[i] = args[i]; - } - for (int i = 0; i < kwcount; i++) { - Py_INCREF(kws[2*i]); - PyTuple_SET_ITEM(kwnames, i, kws[2*i]); - newargs[argcount+i] = kws[2*i+1]; - } - allargs = newargs; - } - for (int i = 0; i < kwcount; i++) { - Py_INCREF(kws[2*i]); - PyTuple_SET_ITEM(kwnames, i, kws[2*i]); - } - PyFrameConstructor constr = { - .fc_globals = globals, - .fc_builtins = builtins, - .fc_name = ((PyCodeObject *)_co)->co_name, - .fc_qualname = ((PyCodeObject *)_co)->co_name, - .fc_code = _co, - .fc_defaults = defaults, - .fc_kwdefaults = kwdefs, - .fc_closure = closure - }; - res = _PyEval_Vector(tstate, &constr, locals, - allargs, argcount, - kwnames); -fail: - Py_XDECREF(kwnames); - PyMem_Free(newargs); - Py_DECREF(defaults); - return res; -} - - -static PyObject * -special_lookup(PyThreadState *tstate, PyObject *o, _Py_Identifier *id) -{ - PyObject *res; - res = _PyObject_LookupSpecial(o, id); - if (res == NULL && !_PyErr_Occurred(tstate)) { - _PyErr_SetObject(tstate, PyExc_AttributeError, _PyUnicode_FromId(id)); - return NULL; - } - return res; -} - - -/* Logic for the raise statement (too complicated for inlining). - This *consumes* a reference count to each of its arguments. */ -static int -do_raise(PyThreadState *tstate, PyObject *exc, PyObject *cause) -{ - PyObject *type = NULL, *value = NULL; - - if (exc == NULL) { - /* Reraise */ - _PyErr_StackItem *exc_info = _PyErr_GetTopmostException(tstate); - PyObject *tb; - type = exc_info->exc_type; - value = exc_info->exc_value; - tb = exc_info->exc_traceback; - if (Py_IsNone(type) || type == NULL) { - _PyErr_SetString(tstate, PyExc_RuntimeError, - "No active exception to reraise"); - return 0; - } - Py_XINCREF(type); - Py_XINCREF(value); - Py_XINCREF(tb); - _PyErr_Restore(tstate, type, value, tb); - return 1; - } - - /* We support the following forms of raise: - raise - raise <instance> - raise <type> */ - - if (PyExceptionClass_Check(exc)) { - type = exc; - value = _PyObject_CallNoArg(exc); - if (value == NULL) - goto raise_error; - if (!PyExceptionInstance_Check(value)) { - _PyErr_Format(tstate, PyExc_TypeError, - "calling %R should have returned an instance of " - "BaseException, not %R", - type, Py_TYPE(value)); - goto raise_error; - } - } - else if (PyExceptionInstance_Check(exc)) { - value = exc; - type = PyExceptionInstance_Class(exc); - Py_INCREF(type); - } - else { - /* Not something you can raise. You get an exception - anyway, just not what you specified :-) */ - Py_DECREF(exc); - _PyErr_SetString(tstate, PyExc_TypeError, - "exceptions must derive from BaseException"); - goto raise_error; - } - - assert(type != NULL); - assert(value != NULL); - - if (cause) { - PyObject *fixed_cause; - if (PyExceptionClass_Check(cause)) { - fixed_cause = _PyObject_CallNoArg(cause); - if (fixed_cause == NULL) - goto raise_error; - Py_DECREF(cause); - } - else if (PyExceptionInstance_Check(cause)) { - fixed_cause = cause; - } - else if (Py_IsNone(cause)) { - Py_DECREF(cause); - fixed_cause = NULL; - } - else { - _PyErr_SetString(tstate, PyExc_TypeError, - "exception causes must derive from " - "BaseException"); - goto raise_error; - } - PyException_SetCause(value, fixed_cause); - } - - _PyErr_SetObject(tstate, type, value); - /* _PyErr_SetObject incref's its arguments */ - Py_DECREF(value); - Py_DECREF(type); - return 0; - -raise_error: - Py_XDECREF(value); - Py_XDECREF(type); - Py_XDECREF(cause); - return 0; -} - -/* Iterate v argcnt times and store the results on the stack (via decreasing - sp). Return 1 for success, 0 if error. - - If argcntafter == -1, do a simple unpack. If it is >= 0, do an unpack - with a variable target. -*/ - -static int -unpack_iterable(PyThreadState *tstate, PyObject *v, - int argcnt, int argcntafter, PyObject **sp) -{ - int i = 0, j = 0; - Py_ssize_t ll = 0; - PyObject *it; /* iter(v) */ - PyObject *w; - PyObject *l = NULL; /* variable list */ - - assert(v != NULL); - - it = PyObject_GetIter(v); - if (it == NULL) { - if (_PyErr_ExceptionMatches(tstate, PyExc_TypeError) && - Py_TYPE(v)->tp_iter == NULL && !PySequence_Check(v)) - { - _PyErr_Format(tstate, PyExc_TypeError, - "cannot unpack non-iterable %.200s object", - Py_TYPE(v)->tp_name); - } - return 0; - } - - for (; i < argcnt; i++) { - w = PyIter_Next(it); - if (w == NULL) { - /* Iterator done, via error or exhaustion. */ - if (!_PyErr_Occurred(tstate)) { - if (argcntafter == -1) { - _PyErr_Format(tstate, PyExc_ValueError, - "not enough values to unpack " - "(expected %d, got %d)", - argcnt, i); - } - else { - _PyErr_Format(tstate, PyExc_ValueError, - "not enough values to unpack " - "(expected at least %d, got %d)", - argcnt + argcntafter, i); - } - } - goto Error; - } - *--sp = w; - } - - if (argcntafter == -1) { - /* We better have exhausted the iterator now. */ - w = PyIter_Next(it); - if (w == NULL) { - if (_PyErr_Occurred(tstate)) - goto Error; - Py_DECREF(it); - return 1; - } - Py_DECREF(w); - _PyErr_Format(tstate, PyExc_ValueError, - "too many values to unpack (expected %d)", - argcnt); - goto Error; - } - - l = PySequence_List(it); - if (l == NULL) - goto Error; - *--sp = l; - i++; - - ll = PyList_GET_SIZE(l); - if (ll < argcntafter) { - _PyErr_Format(tstate, PyExc_ValueError, - "not enough values to unpack (expected at least %d, got %zd)", - argcnt + argcntafter, argcnt + ll); - goto Error; - } - - /* Pop the "after-variable" args off the list. */ - for (j = argcntafter; j > 0; j--, i++) { - *--sp = PyList_GET_ITEM(l, ll - j); - } - /* Resize the list. */ - Py_SET_SIZE(l, ll - argcntafter); - Py_DECREF(it); - return 1; - -Error: - for (; i > 0; i--, sp++) - Py_DECREF(*sp); - Py_XDECREF(it); - return 0; -} - -#ifdef LLTRACE -static int -prtrace(PyThreadState *tstate, PyObject *v, const char *str) -{ - printf("%s ", str); - PyObject *type, *value, *traceback; - PyErr_Fetch(&type, &value, &traceback); - if (PyObject_Print(v, stdout, 0) != 0) { - /* Don't know what else to do */ - _PyErr_Clear(tstate); - } - printf("\n"); - PyErr_Restore(type, value, traceback); - // gh-91924: PyObject_Print() can indirectly set lltrace to 0 - lltrace = 1; - return 1; -} -#endif - -static void -call_exc_trace(Py_tracefunc func, PyObject *self, - PyThreadState *tstate, - PyFrameObject *f, - PyTraceInfo *trace_info) -{ - PyObject *type, *value, *traceback, *orig_traceback, *arg; - int err; - _PyErr_Fetch(tstate, &type, &value, &orig_traceback); - if (value == NULL) { - value = Py_None; - Py_INCREF(value); - } - _PyErr_NormalizeException(tstate, &type, &value, &orig_traceback); - traceback = (orig_traceback != NULL) ? orig_traceback : Py_None; - arg = PyTuple_Pack(3, type, value, traceback); - if (arg == NULL) { - _PyErr_Restore(tstate, type, value, orig_traceback); - return; - } - err = call_trace(func, self, tstate, f, trace_info, PyTrace_EXCEPTION, arg); - Py_DECREF(arg); - if (err == 0) { - _PyErr_Restore(tstate, type, value, orig_traceback); - } - else { - Py_XDECREF(type); - Py_XDECREF(value); - Py_XDECREF(orig_traceback); - } -} - -static int -call_trace_protected(Py_tracefunc func, PyObject *obj, - PyThreadState *tstate, PyFrameObject *frame, - PyTraceInfo *trace_info, - int what, PyObject *arg) -{ - PyObject *type, *value, *traceback; - int err; - _PyErr_Fetch(tstate, &type, &value, &traceback); - err = call_trace(func, obj, tstate, frame, trace_info, what, arg); - if (err == 0) - { - _PyErr_Restore(tstate, type, value, traceback); - return 0; - } - else { - Py_XDECREF(type); - Py_XDECREF(value); - Py_XDECREF(traceback); - return -1; - } -} - -static void -initialize_trace_info(PyTraceInfo *trace_info, PyFrameObject *frame) -{ - if (trace_info->code != frame->f_code) { - trace_info->code = frame->f_code; - _PyCode_InitAddressRange(frame->f_code, &trace_info->bounds); - } -} - -static int -call_trace(Py_tracefunc func, PyObject *obj, - PyThreadState *tstate, PyFrameObject *frame, - PyTraceInfo *trace_info, - int what, PyObject *arg) -{ - int result; - if (tstate->tracing) - return 0; - tstate->tracing++; - tstate->cframe->use_tracing = 0; - if (frame->f_lasti < 0) { - frame->f_lineno = frame->f_code->co_firstlineno; - } - else { - initialize_trace_info(trace_info, frame); - frame->f_lineno = _PyCode_CheckLineNumber(frame->f_lasti*sizeof(_Py_CODEUNIT), &trace_info->bounds); - } - result = func(obj, frame, what, arg); - frame->f_lineno = 0; - tstate->cframe->use_tracing = ((tstate->c_tracefunc != NULL) - || (tstate->c_profilefunc != NULL)); - tstate->tracing--; - return result; -} - -PyObject * -_PyEval_CallTracing(PyObject *func, PyObject *args) -{ - PyThreadState *tstate = _PyThreadState_GET(); - int save_tracing = tstate->tracing; - int save_use_tracing = tstate->cframe->use_tracing; - PyObject *result; - - tstate->tracing = 0; - tstate->cframe->use_tracing = ((tstate->c_tracefunc != NULL) - || (tstate->c_profilefunc != NULL)); - result = PyObject_Call(func, args, NULL); - tstate->tracing = save_tracing; - tstate->cframe->use_tracing = save_use_tracing; - return result; -} - -/* See Objects/lnotab_notes.txt for a description of how tracing works. */ -static int -maybe_call_line_trace(Py_tracefunc func, PyObject *obj, - PyThreadState *tstate, PyFrameObject *frame, - PyTraceInfo *trace_info, int instr_prev) -{ - int result = 0; - - /* If the last instruction falls at the start of a line or if it - represents a jump backwards, update the frame's line number and - then call the trace function if we're tracing source lines. - */ - initialize_trace_info(trace_info, frame); - int lastline = _PyCode_CheckLineNumber(instr_prev*sizeof(_Py_CODEUNIT), &trace_info->bounds); - int line = _PyCode_CheckLineNumber(frame->f_lasti*sizeof(_Py_CODEUNIT), &trace_info->bounds); - if (line != -1 && frame->f_trace_lines) { - /* Trace backward edges or if line number has changed */ - if (frame->f_lasti < instr_prev || line != lastline) { - result = call_trace(func, obj, tstate, frame, trace_info, PyTrace_LINE, Py_None); - } - } - /* Always emit an opcode event if we're tracing all opcodes. */ - if (frame->f_trace_opcodes) { - result = call_trace(func, obj, tstate, frame, trace_info, PyTrace_OPCODE, Py_None); - } - return result; -} - -int -_PyEval_SetProfile(PyThreadState *tstate, Py_tracefunc func, PyObject *arg) -{ - assert(is_tstate_valid(tstate)); - /* The caller must hold the GIL */ - assert(PyGILState_Check()); - - /* Call _PySys_Audit() in the context of the current thread state, - even if tstate is not the current thread state. */ - PyThreadState *current_tstate = _PyThreadState_GET(); - if (_PySys_Audit(current_tstate, "sys.setprofile", NULL) < 0) { - return -1; - } - - PyObject *profileobj = tstate->c_profileobj; - - tstate->c_profilefunc = NULL; - tstate->c_profileobj = NULL; - /* Must make sure that tracing is not ignored if 'profileobj' is freed */ - tstate->cframe->use_tracing = tstate->c_tracefunc != NULL; - Py_XDECREF(profileobj); - - Py_XINCREF(arg); - tstate->c_profileobj = arg; - tstate->c_profilefunc = func; - - /* Flag that tracing or profiling is turned on */ - tstate->cframe->use_tracing = (func != NULL) || (tstate->c_tracefunc != NULL); - return 0; -} - -void -PyEval_SetProfile(Py_tracefunc func, PyObject *arg) -{ - PyThreadState *tstate = _PyThreadState_GET(); - if (_PyEval_SetProfile(tstate, func, arg) < 0) { - /* Log _PySys_Audit() error */ - _PyErr_WriteUnraisableMsg("in PyEval_SetProfile", NULL); - } -} - -int -_PyEval_SetTrace(PyThreadState *tstate, Py_tracefunc func, PyObject *arg) -{ - assert(is_tstate_valid(tstate)); - /* The caller must hold the GIL */ - assert(PyGILState_Check()); - - /* Call _PySys_Audit() in the context of the current thread state, - even if tstate is not the current thread state. */ - PyThreadState *current_tstate = _PyThreadState_GET(); - if (_PySys_Audit(current_tstate, "sys.settrace", NULL) < 0) { - return -1; - } - - PyObject *traceobj = tstate->c_traceobj; - - tstate->c_tracefunc = NULL; - tstate->c_traceobj = NULL; - /* Must make sure that profiling is not ignored if 'traceobj' is freed */ - tstate->cframe->use_tracing = (tstate->c_profilefunc != NULL); - Py_XDECREF(traceobj); - - Py_XINCREF(arg); - tstate->c_traceobj = arg; - tstate->c_tracefunc = func; - - /* Flag that tracing or profiling is turned on */ - tstate->cframe->use_tracing = ((func != NULL) - || (tstate->c_profilefunc != NULL)); - - return 0; -} - -void -PyEval_SetTrace(Py_tracefunc func, PyObject *arg) -{ - PyThreadState *tstate = _PyThreadState_GET(); - if (_PyEval_SetTrace(tstate, func, arg) < 0) { - /* Log _PySys_Audit() error */ - _PyErr_WriteUnraisableMsg("in PyEval_SetTrace", NULL); - } -} - - -void -_PyEval_SetCoroutineOriginTrackingDepth(PyThreadState *tstate, int new_depth) -{ - assert(new_depth >= 0); - tstate->coroutine_origin_tracking_depth = new_depth; -} - -int -_PyEval_GetCoroutineOriginTrackingDepth(void) -{ - PyThreadState *tstate = _PyThreadState_GET(); - return tstate->coroutine_origin_tracking_depth; -} - -int -_PyEval_SetAsyncGenFirstiter(PyObject *firstiter) -{ - PyThreadState *tstate = _PyThreadState_GET(); - - if (_PySys_Audit(tstate, "sys.set_asyncgen_hook_firstiter", NULL) < 0) { - return -1; - } - - Py_XINCREF(firstiter); - Py_XSETREF(tstate->async_gen_firstiter, firstiter); - return 0; -} - -PyObject * -_PyEval_GetAsyncGenFirstiter(void) -{ - PyThreadState *tstate = _PyThreadState_GET(); - return tstate->async_gen_firstiter; -} - -int -_PyEval_SetAsyncGenFinalizer(PyObject *finalizer) -{ - PyThreadState *tstate = _PyThreadState_GET(); - - if (_PySys_Audit(tstate, "sys.set_asyncgen_hook_finalizer", NULL) < 0) { - return -1; - } - - Py_XINCREF(finalizer); - Py_XSETREF(tstate->async_gen_finalizer, finalizer); - return 0; -} - -PyObject * -_PyEval_GetAsyncGenFinalizer(void) -{ - PyThreadState *tstate = _PyThreadState_GET(); - return tstate->async_gen_finalizer; -} - -PyFrameObject * -PyEval_GetFrame(void) -{ - PyThreadState *tstate = _PyThreadState_GET(); - return tstate->frame; -} - -PyObject * -_PyEval_GetBuiltins(PyThreadState *tstate) -{ - PyFrameObject *frame = tstate->frame; - if (frame != NULL) { - return frame->f_builtins; - } - return tstate->interp->builtins; -} - -PyObject * -PyEval_GetBuiltins(void) -{ - PyThreadState *tstate = _PyThreadState_GET(); - return _PyEval_GetBuiltins(tstate); -} - -/* Convenience function to get a builtin from its name */ -PyObject * -_PyEval_GetBuiltinId(_Py_Identifier *name) -{ - PyThreadState *tstate = _PyThreadState_GET(); - PyObject *attr = _PyDict_GetItemIdWithError(PyEval_GetBuiltins(), name); - if (attr) { - Py_INCREF(attr); - } - else if (!_PyErr_Occurred(tstate)) { - _PyErr_SetObject(tstate, PyExc_AttributeError, _PyUnicode_FromId(name)); - } - return attr; -} - -PyObject * -PyEval_GetLocals(void) -{ - PyThreadState *tstate = _PyThreadState_GET(); - PyFrameObject *current_frame = tstate->frame; - if (current_frame == NULL) { - _PyErr_SetString(tstate, PyExc_SystemError, "frame does not exist"); - return NULL; - } - - if (PyFrame_FastToLocalsWithError(current_frame) < 0) { - return NULL; - } - - assert(current_frame->f_locals != NULL); - return current_frame->f_locals; -} - -PyObject * -PyEval_GetGlobals(void) -{ - PyThreadState *tstate = _PyThreadState_GET(); - PyFrameObject *current_frame = tstate->frame; - if (current_frame == NULL) { - return NULL; - } - - assert(current_frame->f_globals != NULL); - return current_frame->f_globals; -} - -int -PyEval_MergeCompilerFlags(PyCompilerFlags *cf) -{ - PyThreadState *tstate = _PyThreadState_GET(); - PyFrameObject *current_frame = tstate->frame; - int result = cf->cf_flags != 0; - - if (current_frame != NULL) { - const int codeflags = current_frame->f_code->co_flags; - const int compilerflags = codeflags & PyCF_MASK; - if (compilerflags) { - result = 1; - cf->cf_flags |= compilerflags; - } -#if 0 /* future keyword */ - if (codeflags & CO_GENERATOR_ALLOWED) { - result = 1; - cf->cf_flags |= CO_GENERATOR_ALLOWED; - } -#endif - } - return result; -} - - -const char * -PyEval_GetFuncName(PyObject *func) -{ - if (PyMethod_Check(func)) - return PyEval_GetFuncName(PyMethod_GET_FUNCTION(func)); - else if (PyFunction_Check(func)) - return PyUnicode_AsUTF8(((PyFunctionObject*)func)->func_name); - else if (PyCFunction_Check(func)) - return ((PyCFunctionObject*)func)->m_ml->ml_name; - else - return Py_TYPE(func)->tp_name; -} - -const char * -PyEval_GetFuncDesc(PyObject *func) -{ - if (PyMethod_Check(func)) - return "()"; - else if (PyFunction_Check(func)) - return "()"; - else if (PyCFunction_Check(func)) - return "()"; - else - return " object"; -} - -#define C_TRACE(x, call) \ -if (trace_info->cframe.use_tracing && tstate->c_profilefunc) { \ - if (call_trace(tstate->c_profilefunc, tstate->c_profileobj, \ - tstate, tstate->frame, trace_info, \ - PyTrace_C_CALL, func)) { \ - x = NULL; \ - } \ - else { \ - x = call; \ - if (tstate->c_profilefunc != NULL) { \ - if (x == NULL) { \ - call_trace_protected(tstate->c_profilefunc, \ - tstate->c_profileobj, \ - tstate, tstate->frame, trace_info, \ - PyTrace_C_EXCEPTION, func); \ - /* XXX should pass (type, value, tb) */ \ - } else { \ - if (call_trace(tstate->c_profilefunc, \ - tstate->c_profileobj, \ - tstate, tstate->frame, trace_info, \ - PyTrace_C_RETURN, func)) { \ - Py_DECREF(x); \ - x = NULL; \ - } \ - } \ - } \ - } \ -} else { \ - x = call; \ - } - - -static PyObject * -trace_call_function(PyThreadState *tstate, - PyTraceInfo *trace_info, - PyObject *func, - PyObject **args, Py_ssize_t nargs, - PyObject *kwnames) -{ - PyObject *x; - if (PyCFunction_CheckExact(func) || PyCMethod_CheckExact(func)) { - C_TRACE(x, PyObject_Vectorcall(func, args, nargs, kwnames)); - return x; - } - else if (Py_IS_TYPE(func, &PyMethodDescr_Type) && nargs > 0) { - /* We need to create a temporary bound method as argument - for profiling. - - If nargs == 0, then this cannot work because we have no - "self". In any case, the call itself would raise - TypeError (foo needs an argument), so we just skip - profiling. */ - PyObject *self = args[0]; - func = Py_TYPE(func)->tp_descr_get(func, self, (PyObject*)Py_TYPE(self)); - if (func == NULL) { - return NULL; - } - C_TRACE(x, PyObject_Vectorcall(func, - args+1, nargs-1, - kwnames)); - Py_DECREF(func); - return x; - } - return PyObject_Vectorcall(func, args, nargs | PY_VECTORCALL_ARGUMENTS_OFFSET, kwnames); -} - -/* Issue #29227: Inline call_function() into _PyEval_EvalFrameDefault() - to reduce the stack consumption. */ -Py_LOCAL_INLINE(PyObject *) _Py_HOT_FUNCTION -call_function(PyThreadState *tstate, - PyTraceInfo *trace_info, - PyObject ***pp_stack, - Py_ssize_t oparg, - PyObject *kwnames) -{ - PyObject **pfunc = (*pp_stack) - oparg - 1; - PyObject *func = *pfunc; - PyObject *x, *w; - Py_ssize_t nkwargs = (kwnames == NULL) ? 0 : PyTuple_GET_SIZE(kwnames); - Py_ssize_t nargs = oparg - nkwargs; - PyObject **stack = (*pp_stack) - nargs - nkwargs; - - if (trace_info->cframe.use_tracing) { - x = trace_call_function(tstate, trace_info, func, stack, nargs, kwnames); - } - else { - x = PyObject_Vectorcall(func, stack, nargs | PY_VECTORCALL_ARGUMENTS_OFFSET, kwnames); - } - - assert((x != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); - - /* Clear the stack of the function object. */ - while ((*pp_stack) > pfunc) { - w = EXT_POP(*pp_stack); - Py_DECREF(w); - } - - return x; -} - -static PyObject * -do_call_core(PyThreadState *tstate, - PyTraceInfo *trace_info, - PyObject *func, - PyObject *callargs, - PyObject *kwdict) -{ - PyObject *result; - - if (PyCFunction_CheckExact(func) || PyCMethod_CheckExact(func)) { - C_TRACE(result, PyObject_Call(func, callargs, kwdict)); - return result; - } - else if (Py_IS_TYPE(func, &PyMethodDescr_Type)) { - Py_ssize_t nargs = PyTuple_GET_SIZE(callargs); - if (nargs > 0 && trace_info->cframe.use_tracing) { - /* We need to create a temporary bound method as argument - for profiling. - - If nargs == 0, then this cannot work because we have no - "self". In any case, the call itself would raise - TypeError (foo needs an argument), so we just skip - profiling. */ - PyObject *self = PyTuple_GET_ITEM(callargs, 0); - func = Py_TYPE(func)->tp_descr_get(func, self, (PyObject*)Py_TYPE(self)); - if (func == NULL) { - return NULL; - } - - C_TRACE(result, _PyObject_FastCallDictTstate( - tstate, func, - &_PyTuple_ITEMS(callargs)[1], - nargs - 1, - kwdict)); - Py_DECREF(func); - return result; - } - } - return PyObject_Call(func, callargs, kwdict); -} - -/* Extract a slice index from a PyLong or an object with the - nb_index slot defined, and store in *pi. - Silently reduce values larger than PY_SSIZE_T_MAX to PY_SSIZE_T_MAX, - and silently boost values less than PY_SSIZE_T_MIN to PY_SSIZE_T_MIN. - Return 0 on error, 1 on success. -*/ -int -_PyEval_SliceIndex(PyObject *v, Py_ssize_t *pi) -{ - PyThreadState *tstate = _PyThreadState_GET(); - if (!Py_IsNone(v)) { - Py_ssize_t x; - if (_PyIndex_Check(v)) { - x = PyNumber_AsSsize_t(v, NULL); - if (x == -1 && _PyErr_Occurred(tstate)) - return 0; - } - else { - _PyErr_SetString(tstate, PyExc_TypeError, - "slice indices must be integers or " - "None or have an __index__ method"); - return 0; - } - *pi = x; - } - return 1; -} - -int -_PyEval_SliceIndexNotNone(PyObject *v, Py_ssize_t *pi) -{ - PyThreadState *tstate = _PyThreadState_GET(); - Py_ssize_t x; - if (_PyIndex_Check(v)) { - x = PyNumber_AsSsize_t(v, NULL); - if (x == -1 && _PyErr_Occurred(tstate)) - return 0; - } - else { - _PyErr_SetString(tstate, PyExc_TypeError, - "slice indices must be integers or " - "have an __index__ method"); - return 0; - } - *pi = x; - return 1; -} - -static PyObject * -import_name(PyThreadState *tstate, PyFrameObject *f, - PyObject *name, PyObject *fromlist, PyObject *level) -{ - _Py_IDENTIFIER(__import__); - PyObject *import_func, *res; - PyObject* stack[5]; - - import_func = _PyDict_GetItemIdWithError(f->f_builtins, &PyId___import__); - if (import_func == NULL) { - if (!_PyErr_Occurred(tstate)) { - _PyErr_SetString(tstate, PyExc_ImportError, "__import__ not found"); - } - return NULL; - } - - /* Fast path for not overloaded __import__. */ - if (import_func == tstate->interp->import_func) { - int ilevel = _PyLong_AsInt(level); - if (ilevel == -1 && _PyErr_Occurred(tstate)) { - return NULL; - } - res = PyImport_ImportModuleLevelObject( - name, - f->f_globals, - f->f_locals == NULL ? Py_None : f->f_locals, - fromlist, - ilevel); - return res; - } - - Py_INCREF(import_func); - - stack[0] = name; - stack[1] = f->f_globals; - stack[2] = f->f_locals == NULL ? Py_None : f->f_locals; - stack[3] = fromlist; - stack[4] = level; - res = _PyObject_FastCall(import_func, stack, 5); - Py_DECREF(import_func); - return res; -} - -static PyObject * -import_from(PyThreadState *tstate, PyObject *v, PyObject *name) -{ - PyObject *x; - PyObject *fullmodname, *pkgname, *pkgpath, *pkgname_or_unknown, *errmsg; - - if (_PyObject_LookupAttr(v, name, &x) != 0) { - return x; - } - /* Issue #17636: in case this failed because of a circular relative - import, try to fallback on reading the module directly from - sys.modules. */ - pkgname = _PyObject_GetAttrId(v, &PyId___name__); - if (pkgname == NULL) { - goto error; - } - if (!PyUnicode_Check(pkgname)) { - Py_CLEAR(pkgname); - goto error; - } - fullmodname = PyUnicode_FromFormat("%U.%U", pkgname, name); - if (fullmodname == NULL) { - Py_DECREF(pkgname); - return NULL; - } - x = PyImport_GetModule(fullmodname); - Py_DECREF(fullmodname); - if (x == NULL && !_PyErr_Occurred(tstate)) { - goto error; - } - Py_DECREF(pkgname); - return x; - error: - pkgpath = PyModule_GetFilenameObject(v); - if (pkgname == NULL) { - pkgname_or_unknown = PyUnicode_FromString("<unknown module name>"); - if (pkgname_or_unknown == NULL) { - Py_XDECREF(pkgpath); - return NULL; - } - } else { - pkgname_or_unknown = pkgname; - } - - if (pkgpath == NULL || !PyUnicode_Check(pkgpath)) { - _PyErr_Clear(tstate); - errmsg = PyUnicode_FromFormat( - "cannot import name %R from %R (unknown location)", - name, pkgname_or_unknown - ); - /* NULL checks for errmsg and pkgname done by PyErr_SetImportError. */ - PyErr_SetImportError(errmsg, pkgname, NULL); - } - else { - _Py_IDENTIFIER(__spec__); - PyObject *spec = _PyObject_GetAttrId(v, &PyId___spec__); - const char *fmt = - _PyModuleSpec_IsInitializing(spec) ? - "cannot import name %R from partially initialized module %R " - "(most likely due to a circular import) (%S)" : - "cannot import name %R from %R (%S)"; - Py_XDECREF(spec); - - errmsg = PyUnicode_FromFormat(fmt, name, pkgname_or_unknown, pkgpath); - /* NULL checks for errmsg and pkgname done by PyErr_SetImportError. */ - PyErr_SetImportError(errmsg, pkgname, pkgpath); - } - - Py_XDECREF(errmsg); - Py_XDECREF(pkgname_or_unknown); - Py_XDECREF(pkgpath); - return NULL; -} - -static int -import_all_from(PyThreadState *tstate, PyObject *locals, PyObject *v) -{ - _Py_IDENTIFIER(__all__); - _Py_IDENTIFIER(__dict__); - PyObject *all, *dict, *name, *value; - int skip_leading_underscores = 0; - int pos, err; - - if (_PyObject_LookupAttrId(v, &PyId___all__, &all) < 0) { - return -1; /* Unexpected error */ - } - if (all == NULL) { - if (_PyObject_LookupAttrId(v, &PyId___dict__, &dict) < 0) { - return -1; - } - if (dict == NULL) { - _PyErr_SetString(tstate, PyExc_ImportError, - "from-import-* object has no __dict__ and no __all__"); - return -1; - } - all = PyMapping_Keys(dict); - Py_DECREF(dict); - if (all == NULL) - return -1; - skip_leading_underscores = 1; - } - - for (pos = 0, err = 0; ; pos++) { - name = PySequence_GetItem(all, pos); - if (name == NULL) { - if (!_PyErr_ExceptionMatches(tstate, PyExc_IndexError)) { - err = -1; - } - else { - _PyErr_Clear(tstate); - } - break; - } - if (!PyUnicode_Check(name)) { - PyObject *modname = _PyObject_GetAttrId(v, &PyId___name__); - if (modname == NULL) { - Py_DECREF(name); - err = -1; - break; - } - if (!PyUnicode_Check(modname)) { - _PyErr_Format(tstate, PyExc_TypeError, - "module __name__ must be a string, not %.100s", - Py_TYPE(modname)->tp_name); - } - else { - _PyErr_Format(tstate, PyExc_TypeError, - "%s in %U.%s must be str, not %.100s", - skip_leading_underscores ? "Key" : "Item", - modname, - skip_leading_underscores ? "__dict__" : "__all__", - Py_TYPE(name)->tp_name); - } - Py_DECREF(modname); - Py_DECREF(name); - err = -1; - break; - } - if (skip_leading_underscores) { - if (PyUnicode_READY(name) == -1) { - Py_DECREF(name); - err = -1; - break; - } - if (PyUnicode_READ_CHAR(name, 0) == '_') { - Py_DECREF(name); - continue; - } - } - value = PyObject_GetAttr(v, name); - if (value == NULL) - err = -1; - else if (PyDict_CheckExact(locals)) - err = PyDict_SetItem(locals, name, value); - else - err = PyObject_SetItem(locals, name, value); - Py_DECREF(name); - Py_XDECREF(value); - if (err != 0) - break; - } - Py_DECREF(all); - return err; -} - -static int -check_args_iterable(PyThreadState *tstate, PyObject *func, PyObject *args) -{ - if (Py_TYPE(args)->tp_iter == NULL && !PySequence_Check(args)) { - /* check_args_iterable() may be called with a live exception: - * clear it to prevent calling _PyObject_FunctionStr() with an - * exception set. */ - _PyErr_Clear(tstate); - PyObject *funcstr = _PyObject_FunctionStr(func); - if (funcstr != NULL) { - _PyErr_Format(tstate, PyExc_TypeError, - "%U argument after * must be an iterable, not %.200s", - funcstr, Py_TYPE(args)->tp_name); - Py_DECREF(funcstr); - } - return -1; - } - return 0; -} - -static void -format_kwargs_error(PyThreadState *tstate, PyObject *func, PyObject *kwargs) -{ - /* _PyDict_MergeEx raises attribute - * error (percolated from an attempt - * to get 'keys' attribute) instead of - * a type error if its second argument - * is not a mapping. - */ - if (_PyErr_ExceptionMatches(tstate, PyExc_AttributeError)) { - _PyErr_Clear(tstate); - PyObject *funcstr = _PyObject_FunctionStr(func); - if (funcstr != NULL) { - _PyErr_Format( - tstate, PyExc_TypeError, - "%U argument after ** must be a mapping, not %.200s", - funcstr, Py_TYPE(kwargs)->tp_name); - Py_DECREF(funcstr); - } - } - else if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { - PyObject *exc, *val, *tb; - _PyErr_Fetch(tstate, &exc, &val, &tb); - if (val && PyTuple_Check(val) && PyTuple_GET_SIZE(val) == 1) { - _PyErr_Clear(tstate); - PyObject *funcstr = _PyObject_FunctionStr(func); - if (funcstr != NULL) { - PyObject *key = PyTuple_GET_ITEM(val, 0); - _PyErr_Format( - tstate, PyExc_TypeError, - "%U got multiple values for keyword argument '%S'", - funcstr, key); - Py_DECREF(funcstr); - } - Py_XDECREF(exc); - Py_XDECREF(val); - Py_XDECREF(tb); - } - else { - _PyErr_Restore(tstate, exc, val, tb); - } - } -} - -static void -format_exc_check_arg(PyThreadState *tstate, PyObject *exc, - const char *format_str, PyObject *obj) -{ - const char *obj_str; - - if (!obj) - return; - - obj_str = PyUnicode_AsUTF8(obj); - if (!obj_str) - return; - - _PyErr_Format(tstate, exc, format_str, obj_str); - - if (exc == PyExc_NameError) { - // Include the name in the NameError exceptions to offer suggestions later. - _Py_IDENTIFIER(name); - PyObject *type, *value, *traceback; - PyErr_Fetch(&type, &value, &traceback); - PyErr_NormalizeException(&type, &value, &traceback); - if (PyErr_GivenExceptionMatches(value, PyExc_NameError)) { - PyNameErrorObject* exc = (PyNameErrorObject*) value; - if (exc->name == NULL) { - // We do not care if this fails because we are going to restore the - // NameError anyway. - (void)_PyObject_SetAttrId(value, &PyId_name, obj); - } - } - PyErr_Restore(type, value, traceback); - } -} - -static void -format_exc_unbound(PyThreadState *tstate, PyCodeObject *co, int oparg) -{ - PyObject *name; - /* Don't stomp existing exception */ - if (_PyErr_Occurred(tstate)) - return; - if (oparg < PyTuple_GET_SIZE(co->co_cellvars)) { - name = PyTuple_GET_ITEM(co->co_cellvars, - oparg); - format_exc_check_arg(tstate, - PyExc_UnboundLocalError, - UNBOUNDLOCAL_ERROR_MSG, - name); - } else { - name = PyTuple_GET_ITEM(co->co_freevars, oparg - - PyTuple_GET_SIZE(co->co_cellvars)); - format_exc_check_arg(tstate, PyExc_NameError, - UNBOUNDFREE_ERROR_MSG, name); - } -} - -static void -format_awaitable_error(PyThreadState *tstate, PyTypeObject *type, int prevprevopcode, int prevopcode) -{ - if (type->tp_as_async == NULL || type->tp_as_async->am_await == NULL) { - if (prevopcode == BEFORE_ASYNC_WITH) { - _PyErr_Format(tstate, PyExc_TypeError, - "'async with' received an object from __aenter__ " - "that does not implement __await__: %.100s", - type->tp_name); - } - else if (prevopcode == WITH_EXCEPT_START || (prevopcode == CALL_FUNCTION && prevprevopcode == DUP_TOP)) { - _PyErr_Format(tstate, PyExc_TypeError, - "'async with' received an object from __aexit__ " - "that does not implement __await__: %.100s", - type->tp_name); - } - } -} - -static PyObject * -unicode_concatenate(PyThreadState *tstate, PyObject *v, PyObject *w, - PyFrameObject *f, const _Py_CODEUNIT *next_instr) -{ - PyObject *res; - if (Py_REFCNT(v) == 2) { - /* In the common case, there are 2 references to the value - * stored in 'variable' when the += is performed: one on the - * value stack (in 'v') and one still stored in the - * 'variable'. We try to delete the variable now to reduce - * the refcnt to 1. - */ - int opcode, oparg; - NEXTOPARG(); - switch (opcode) { - case STORE_FAST: - { - PyObject **fastlocals = f->f_localsplus; - if (GETLOCAL(oparg) == v) - SETLOCAL(oparg, NULL); - break; - } - case STORE_DEREF: - { - PyObject **freevars = (f->f_localsplus + - f->f_code->co_nlocals); - PyObject *c = freevars[oparg]; - if (PyCell_GET(c) == v) { - PyCell_SET(c, NULL); - Py_DECREF(v); - } - break; - } - case STORE_NAME: - { - PyObject *names = f->f_code->co_names; - PyObject *name = GETITEM(names, oparg); - PyObject *locals = f->f_locals; - if (locals && PyDict_CheckExact(locals)) { - PyObject *w = PyDict_GetItemWithError(locals, name); - if ((w == v && PyDict_DelItem(locals, name) != 0) || - (w == NULL && _PyErr_Occurred(tstate))) - { - Py_DECREF(v); - return NULL; - } - } - break; - } - } - } - res = v; - PyUnicode_Append(&res, w); - return res; -} - -#ifdef DYNAMIC_EXECUTION_PROFILE - -static PyObject * -getarray(long a[256]) -{ - int i; - PyObject *l = PyList_New(256); - if (l == NULL) return NULL; - for (i = 0; i < 256; i++) { - PyObject *x = PyLong_FromLong(a[i]); - if (x == NULL) { - Py_DECREF(l); - return NULL; - } - PyList_SET_ITEM(l, i, x); - } - for (i = 0; i < 256; i++) - a[i] = 0; - return l; -} - -PyObject * -_Py_GetDXProfile(PyObject *self, PyObject *args) -{ -#ifndef DXPAIRS - return getarray(dxp); -#else - int i; - PyObject *l = PyList_New(257); - if (l == NULL) return NULL; - for (i = 0; i < 257; i++) { - PyObject *x = getarray(dxpairs[i]); - if (x == NULL) { - Py_DECREF(l); - return NULL; - } - PyList_SET_ITEM(l, i, x); - } - return l; -#endif -} - -#endif - -Py_ssize_t -_PyEval_RequestCodeExtraIndex(freefunc free) -{ - PyInterpreterState *interp = _PyInterpreterState_GET(); - Py_ssize_t new_index; - - if (interp->co_extra_user_count == MAX_CO_EXTRA_USERS - 1) { - return -1; - } - new_index = interp->co_extra_user_count++; - interp->co_extra_freefuncs[new_index] = free; - return new_index; -} - -static void -dtrace_function_entry(PyFrameObject *f) -{ - const char *filename; - const char *funcname; - int lineno; - - PyCodeObject *code = f->f_code; - filename = PyUnicode_AsUTF8(code->co_filename); - funcname = PyUnicode_AsUTF8(code->co_name); - lineno = PyFrame_GetLineNumber(f); - - PyDTrace_FUNCTION_ENTRY(filename, funcname, lineno); -} - -static void -dtrace_function_return(PyFrameObject *f) -{ - const char *filename; - const char *funcname; - int lineno; - - PyCodeObject *code = f->f_code; - filename = PyUnicode_AsUTF8(code->co_filename); - funcname = PyUnicode_AsUTF8(code->co_name); - lineno = PyFrame_GetLineNumber(f); - - PyDTrace_FUNCTION_RETURN(filename, funcname, lineno); -} - -/* DTrace equivalent of maybe_call_line_trace. */ -static void -maybe_dtrace_line(PyFrameObject *frame, - PyTraceInfo *trace_info, int instr_prev) -{ - const char *co_filename, *co_name; - - /* If the last instruction executed isn't in the current - instruction window, reset the window. - */ - initialize_trace_info(trace_info, frame); - int line = _PyCode_CheckLineNumber(frame->f_lasti*sizeof(_Py_CODEUNIT), &trace_info->bounds); - /* If the last instruction falls at the start of a line or if - it represents a jump backwards, update the frame's line - number and call the trace function. */ - if (line != frame->f_lineno || frame->f_lasti < instr_prev) { - if (line != -1) { - frame->f_lineno = line; - co_filename = PyUnicode_AsUTF8(frame->f_code->co_filename); - if (!co_filename) - co_filename = "?"; - co_name = PyUnicode_AsUTF8(frame->f_code->co_name); - if (!co_name) - co_name = "?"; - PyDTrace_LINE(co_filename, co_name, line); - } - } -} - - -/* Implement Py_EnterRecursiveCall() and Py_LeaveRecursiveCall() as functions - for the limited API. */ - -#undef Py_EnterRecursiveCall - -int Py_EnterRecursiveCall(const char *where) -{ - return _Py_EnterRecursiveCall_inline(where); -} - -#undef Py_LeaveRecursiveCall - -void Py_LeaveRecursiveCall(void) -{ - _Py_LeaveRecursiveCall_inline(); -} diff --git a/contrib/tools/python3/src/Python/ceval_gil.h b/contrib/tools/python3/src/Python/ceval_gil.h deleted file mode 100644 index 9b8b43253f0..00000000000 --- a/contrib/tools/python3/src/Python/ceval_gil.h +++ /dev/null @@ -1,349 +0,0 @@ -/* - * Implementation of the Global Interpreter Lock (GIL). - */ - -#include <stdlib.h> -#include <errno.h> - -#include "pycore_atomic.h" - - -/* - Notes about the implementation: - - - The GIL is just a boolean variable (locked) whose access is protected - by a mutex (gil_mutex), and whose changes are signalled by a condition - variable (gil_cond). gil_mutex is taken for short periods of time, - and therefore mostly uncontended. - - - In the GIL-holding thread, the main loop (PyEval_EvalFrameEx) must be - able to release the GIL on demand by another thread. A volatile boolean - variable (gil_drop_request) is used for that purpose, which is checked - at every turn of the eval loop. That variable is set after a wait of - `interval` microseconds on `gil_cond` has timed out. - - [Actually, another volatile boolean variable (eval_breaker) is used - which ORs several conditions into one. Volatile booleans are - sufficient as inter-thread signalling means since Python is run - on cache-coherent architectures only.] - - - A thread wanting to take the GIL will first let pass a given amount of - time (`interval` microseconds) before setting gil_drop_request. This - encourages a defined switching period, but doesn't enforce it since - opcodes can take an arbitrary time to execute. - - The `interval` value is available for the user to read and modify - using the Python API `sys.{get,set}switchinterval()`. - - - When a thread releases the GIL and gil_drop_request is set, that thread - ensures that another GIL-awaiting thread gets scheduled. - It does so by waiting on a condition variable (switch_cond) until - the value of last_holder is changed to something else than its - own thread state pointer, indicating that another thread was able to - take the GIL. - - This is meant to prohibit the latency-adverse behaviour on multi-core - machines where one thread would speculatively release the GIL, but still - run and end up being the first to re-acquire it, making the "timeslices" - much longer than expected. - (Note: this mechanism is enabled with FORCE_SWITCHING above) -*/ - -#include "condvar.h" - -#define MUTEX_INIT(mut) \ - if (PyMUTEX_INIT(&(mut))) { \ - Py_FatalError("PyMUTEX_INIT(" #mut ") failed"); }; -#define MUTEX_FINI(mut) \ - if (PyMUTEX_FINI(&(mut))) { \ - Py_FatalError("PyMUTEX_FINI(" #mut ") failed"); }; -#define MUTEX_LOCK(mut) \ - if (PyMUTEX_LOCK(&(mut))) { \ - Py_FatalError("PyMUTEX_LOCK(" #mut ") failed"); }; -#define MUTEX_UNLOCK(mut) \ - if (PyMUTEX_UNLOCK(&(mut))) { \ - Py_FatalError("PyMUTEX_UNLOCK(" #mut ") failed"); }; - -#define COND_INIT(cond) \ - if (PyCOND_INIT(&(cond))) { \ - Py_FatalError("PyCOND_INIT(" #cond ") failed"); }; -#define COND_FINI(cond) \ - if (PyCOND_FINI(&(cond))) { \ - Py_FatalError("PyCOND_FINI(" #cond ") failed"); }; -#define COND_SIGNAL(cond) \ - if (PyCOND_SIGNAL(&(cond))) { \ - Py_FatalError("PyCOND_SIGNAL(" #cond ") failed"); }; -#define COND_WAIT(cond, mut) \ - if (PyCOND_WAIT(&(cond), &(mut))) { \ - Py_FatalError("PyCOND_WAIT(" #cond ") failed"); }; -#define COND_TIMED_WAIT(cond, mut, microseconds, timeout_result) \ - { \ - int r = PyCOND_TIMEDWAIT(&(cond), &(mut), (microseconds)); \ - if (r < 0) \ - Py_FatalError("PyCOND_WAIT(" #cond ") failed"); \ - if (r) /* 1 == timeout, 2 == impl. can't say, so assume timeout */ \ - timeout_result = 1; \ - else \ - timeout_result = 0; \ - } \ - - -#define DEFAULT_INTERVAL 5000 - -static void _gil_initialize(struct _gil_runtime_state *gil) -{ - _Py_atomic_int uninitialized = {-1}; - gil->locked = uninitialized; - gil->interval = DEFAULT_INTERVAL; -} - -static int gil_created(struct _gil_runtime_state *gil) -{ - return (_Py_atomic_load_explicit(&gil->locked, _Py_memory_order_acquire) >= 0); -} - -static void create_gil(struct _gil_runtime_state *gil) -{ - MUTEX_INIT(gil->mutex); -#ifdef FORCE_SWITCHING - MUTEX_INIT(gil->switch_mutex); -#endif - COND_INIT(gil->cond); -#ifdef FORCE_SWITCHING - COND_INIT(gil->switch_cond); -#endif - _Py_atomic_store_relaxed(&gil->last_holder, 0); - _Py_ANNOTATE_RWLOCK_CREATE(&gil->locked); - _Py_atomic_store_explicit(&gil->locked, 0, _Py_memory_order_release); -} - -static void destroy_gil(struct _gil_runtime_state *gil) -{ - /* some pthread-like implementations tie the mutex to the cond - * and must have the cond destroyed first. - */ - COND_FINI(gil->cond); - MUTEX_FINI(gil->mutex); -#ifdef FORCE_SWITCHING - COND_FINI(gil->switch_cond); - MUTEX_FINI(gil->switch_mutex); -#endif - _Py_atomic_store_explicit(&gil->locked, -1, - _Py_memory_order_release); - _Py_ANNOTATE_RWLOCK_DESTROY(&gil->locked); -} - -static void recreate_gil(struct _gil_runtime_state *gil) -{ - _Py_ANNOTATE_RWLOCK_DESTROY(&gil->locked); - /* XXX should we destroy the old OS resources here? */ - create_gil(gil); -} - -static void -drop_gil(struct _ceval_runtime_state *ceval, struct _ceval_state *ceval2, - PyThreadState *tstate) -{ -#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS - struct _gil_runtime_state *gil = &ceval2->gil; -#else - struct _gil_runtime_state *gil = &ceval->gil; -#endif - if (!_Py_atomic_load_relaxed(&gil->locked)) { - Py_FatalError("drop_gil: GIL is not locked"); - } - - /* tstate is allowed to be NULL (early interpreter init) */ - if (tstate != NULL) { - /* Sub-interpreter support: threads might have been switched - under our feet using PyThreadState_Swap(). Fix the GIL last - holder variable so that our heuristics work. */ - _Py_atomic_store_relaxed(&gil->last_holder, (uintptr_t)tstate); - } - - MUTEX_LOCK(gil->mutex); - _Py_ANNOTATE_RWLOCK_RELEASED(&gil->locked, /*is_write=*/1); - _Py_atomic_store_relaxed(&gil->locked, 0); - COND_SIGNAL(gil->cond); - MUTEX_UNLOCK(gil->mutex); - -#ifdef FORCE_SWITCHING - if (_Py_atomic_load_relaxed(&ceval2->gil_drop_request) && tstate != NULL) { - MUTEX_LOCK(gil->switch_mutex); - /* Not switched yet => wait */ - if (((PyThreadState*)_Py_atomic_load_relaxed(&gil->last_holder)) == tstate) - { - assert(is_tstate_valid(tstate)); - RESET_GIL_DROP_REQUEST(tstate->interp); - /* NOTE: if COND_WAIT does not atomically start waiting when - releasing the mutex, another thread can run through, take - the GIL and drop it again, and reset the condition - before we even had a chance to wait for it. */ - COND_WAIT(gil->switch_cond, gil->switch_mutex); - } - MUTEX_UNLOCK(gil->switch_mutex); - } -#endif -} - - -/* Check if a Python thread must exit immediately, rather than taking the GIL - if Py_Finalize() has been called. - - When this function is called by a daemon thread after Py_Finalize() has been - called, the GIL does no longer exist. - - tstate must be non-NULL. */ -static inline int -tstate_must_exit(PyThreadState *tstate) -{ - /* bpo-39877: Access _PyRuntime directly rather than using - tstate->interp->runtime to support calls from Python daemon threads. - After Py_Finalize() has been called, tstate can be a dangling pointer: - point to PyThreadState freed memory. */ - PyThreadState *finalizing = _PyRuntimeState_GetFinalizing(&_PyRuntime); - return (finalizing != NULL && finalizing != tstate); -} - - -/* Take the GIL. - - The function saves errno at entry and restores its value at exit. - - tstate must be non-NULL. */ -static void -take_gil(PyThreadState *tstate) -{ - int err = errno; - - assert(tstate != NULL); - - if (tstate_must_exit(tstate)) { - /* bpo-39877: If Py_Finalize() has been called and tstate is not the - thread which called Py_Finalize(), exit immediately the thread. - - This code path can be reached by a daemon thread after Py_Finalize() - completes. In this case, tstate is a dangling pointer: points to - PyThreadState freed memory. */ - PyThread_exit_thread(); - } - - assert(is_tstate_valid(tstate)); - PyInterpreterState *interp = tstate->interp; - struct _ceval_runtime_state *ceval = &interp->runtime->ceval; - struct _ceval_state *ceval2 = &interp->ceval; -#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS - struct _gil_runtime_state *gil = &ceval2->gil; -#else - struct _gil_runtime_state *gil = &ceval->gil; -#endif - - /* Check that _PyEval_InitThreads() was called to create the lock */ - assert(gil_created(gil)); - - MUTEX_LOCK(gil->mutex); - - if (!_Py_atomic_load_relaxed(&gil->locked)) { - goto _ready; - } - - while (_Py_atomic_load_relaxed(&gil->locked)) { - unsigned long saved_switchnum = gil->switch_number; - - unsigned long interval = (gil->interval >= 1 ? gil->interval : 1); - int timed_out = 0; - COND_TIMED_WAIT(gil->cond, gil->mutex, interval, timed_out); - - /* If we timed out and no switch occurred in the meantime, it is time - to ask the GIL-holding thread to drop it. */ - if (timed_out && - _Py_atomic_load_relaxed(&gil->locked) && - gil->switch_number == saved_switchnum) - { - if (tstate_must_exit(tstate)) { - MUTEX_UNLOCK(gil->mutex); - PyThread_exit_thread(); - } - assert(is_tstate_valid(tstate)); - - SET_GIL_DROP_REQUEST(interp); - } - } - -_ready: -#ifdef FORCE_SWITCHING - /* This mutex must be taken before modifying gil->last_holder: - see drop_gil(). */ - MUTEX_LOCK(gil->switch_mutex); -#endif - /* We now hold the GIL */ - _Py_atomic_store_relaxed(&gil->locked, 1); - _Py_ANNOTATE_RWLOCK_ACQUIRED(&gil->locked, /*is_write=*/1); - - if (tstate != (PyThreadState*)_Py_atomic_load_relaxed(&gil->last_holder)) { - _Py_atomic_store_relaxed(&gil->last_holder, (uintptr_t)tstate); - ++gil->switch_number; - } - -#ifdef FORCE_SWITCHING - COND_SIGNAL(gil->switch_cond); - MUTEX_UNLOCK(gil->switch_mutex); -#endif - - if (tstate_must_exit(tstate)) { - /* bpo-36475: If Py_Finalize() has been called and tstate is not - the thread which called Py_Finalize(), exit immediately the - thread. - - This code path can be reached by a daemon thread which was waiting - in take_gil() while the main thread called - wait_for_thread_shutdown() from Py_Finalize(). */ - MUTEX_UNLOCK(gil->mutex); - drop_gil(ceval, ceval2, tstate); - PyThread_exit_thread(); - } - assert(is_tstate_valid(tstate)); - - if (_Py_atomic_load_relaxed(&ceval2->gil_drop_request)) { - RESET_GIL_DROP_REQUEST(interp); - } - else { - /* bpo-40010: eval_breaker should be recomputed to be set to 1 if there - is a pending signal: signal received by another thread which cannot - handle signals. - - Note: RESET_GIL_DROP_REQUEST() calls COMPUTE_EVAL_BREAKER(). */ - COMPUTE_EVAL_BREAKER(interp, ceval, ceval2); - } - - /* Don't access tstate if the thread must exit */ - if (tstate->async_exc != NULL) { - _PyEval_SignalAsyncExc(tstate->interp); - } - - MUTEX_UNLOCK(gil->mutex); - - errno = err; -} - -void _PyEval_SetSwitchInterval(unsigned long microseconds) -{ -#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS - PyInterpreterState *interp = PyInterpreterState_Get(); - struct _gil_runtime_state *gil = &interp->ceval.gil; -#else - struct _gil_runtime_state *gil = &_PyRuntime.ceval.gil; -#endif - gil->interval = microseconds; -} - -unsigned long _PyEval_GetSwitchInterval() -{ -#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS - PyInterpreterState *interp = PyInterpreterState_Get(); - struct _gil_runtime_state *gil = &interp->ceval.gil; -#else - struct _gil_runtime_state *gil = &_PyRuntime.ceval.gil; -#endif - return gil->interval; -} diff --git a/contrib/tools/python3/src/Python/clinic/_warnings.c.h b/contrib/tools/python3/src/Python/clinic/_warnings.c.h deleted file mode 100644 index ad6b9a8e242..00000000000 --- a/contrib/tools/python3/src/Python/clinic/_warnings.c.h +++ /dev/null @@ -1,69 +0,0 @@ -/*[clinic input] -preserve -[clinic start generated code]*/ - -PyDoc_STRVAR(warnings_warn__doc__, -"warn($module, /, message, category=None, stacklevel=1, source=None)\n" -"--\n" -"\n" -"Issue a warning, or maybe ignore it or raise an exception."); - -#define WARNINGS_WARN_METHODDEF \ - {"warn", (PyCFunction)(void(*)(void))warnings_warn, METH_FASTCALL|METH_KEYWORDS, warnings_warn__doc__}, - -static PyObject * -warnings_warn_impl(PyObject *module, PyObject *message, PyObject *category, - Py_ssize_t stacklevel, PyObject *source); - -static PyObject * -warnings_warn(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"message", "category", "stacklevel", "source", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "warn", 0}; - PyObject *argsbuf[4]; - Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - PyObject *message; - PyObject *category = Py_None; - Py_ssize_t stacklevel = 1; - PyObject *source = Py_None; - - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 4, 0, argsbuf); - if (!args) { - goto exit; - } - message = args[0]; - if (!noptargs) { - goto skip_optional_pos; - } - if (args[1]) { - category = args[1]; - if (!--noptargs) { - goto skip_optional_pos; - } - } - if (args[2]) { - { - Py_ssize_t ival = -1; - PyObject *iobj = _PyNumber_Index(args[2]); - if (iobj != NULL) { - ival = PyLong_AsSsize_t(iobj); - Py_DECREF(iobj); - } - if (ival == -1 && PyErr_Occurred()) { - goto exit; - } - stacklevel = ival; - } - if (!--noptargs) { - goto skip_optional_pos; - } - } - source = args[3]; -skip_optional_pos: - return_value = warnings_warn_impl(module, message, category, stacklevel, source); - -exit: - return return_value; -} -/*[clinic end generated code: output=eb9997fa998fdbad input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Python/clinic/bltinmodule.c.h b/contrib/tools/python3/src/Python/clinic/bltinmodule.c.h deleted file mode 100644 index 545f5b53f6e..00000000000 --- a/contrib/tools/python3/src/Python/clinic/bltinmodule.c.h +++ /dev/null @@ -1,877 +0,0 @@ -/*[clinic input] -preserve -[clinic start generated code]*/ - -PyDoc_STRVAR(builtin_abs__doc__, -"abs($module, x, /)\n" -"--\n" -"\n" -"Return the absolute value of the argument."); - -#define BUILTIN_ABS_METHODDEF \ - {"abs", (PyCFunction)builtin_abs, METH_O, builtin_abs__doc__}, - -PyDoc_STRVAR(builtin_all__doc__, -"all($module, iterable, /)\n" -"--\n" -"\n" -"Return True if bool(x) is True for all values x in the iterable.\n" -"\n" -"If the iterable is empty, return True."); - -#define BUILTIN_ALL_METHODDEF \ - {"all", (PyCFunction)builtin_all, METH_O, builtin_all__doc__}, - -PyDoc_STRVAR(builtin_any__doc__, -"any($module, iterable, /)\n" -"--\n" -"\n" -"Return True if bool(x) is True for any x in the iterable.\n" -"\n" -"If the iterable is empty, return False."); - -#define BUILTIN_ANY_METHODDEF \ - {"any", (PyCFunction)builtin_any, METH_O, builtin_any__doc__}, - -PyDoc_STRVAR(builtin_ascii__doc__, -"ascii($module, obj, /)\n" -"--\n" -"\n" -"Return an ASCII-only representation of an object.\n" -"\n" -"As repr(), return a string containing a printable representation of an\n" -"object, but escape the non-ASCII characters in the string returned by\n" -"repr() using \\\\x, \\\\u or \\\\U escapes. This generates a string similar\n" -"to that returned by repr() in Python 2."); - -#define BUILTIN_ASCII_METHODDEF \ - {"ascii", (PyCFunction)builtin_ascii, METH_O, builtin_ascii__doc__}, - -PyDoc_STRVAR(builtin_bin__doc__, -"bin($module, number, /)\n" -"--\n" -"\n" -"Return the binary representation of an integer.\n" -"\n" -" >>> bin(2796202)\n" -" \'0b1010101010101010101010\'"); - -#define BUILTIN_BIN_METHODDEF \ - {"bin", (PyCFunction)builtin_bin, METH_O, builtin_bin__doc__}, - -PyDoc_STRVAR(builtin_callable__doc__, -"callable($module, obj, /)\n" -"--\n" -"\n" -"Return whether the object is callable (i.e., some kind of function).\n" -"\n" -"Note that classes are callable, as are instances of classes with a\n" -"__call__() method."); - -#define BUILTIN_CALLABLE_METHODDEF \ - {"callable", (PyCFunction)builtin_callable, METH_O, builtin_callable__doc__}, - -PyDoc_STRVAR(builtin_format__doc__, -"format($module, value, format_spec=\'\', /)\n" -"--\n" -"\n" -"Return value.__format__(format_spec)\n" -"\n" -"format_spec defaults to the empty string.\n" -"See the Format Specification Mini-Language section of help(\'FORMATTING\') for\n" -"details."); - -#define BUILTIN_FORMAT_METHODDEF \ - {"format", (PyCFunction)(void(*)(void))builtin_format, METH_FASTCALL, builtin_format__doc__}, - -static PyObject * -builtin_format_impl(PyObject *module, PyObject *value, PyObject *format_spec); - -static PyObject * -builtin_format(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *value; - PyObject *format_spec = NULL; - - if (!_PyArg_CheckPositional("format", nargs, 1, 2)) { - goto exit; - } - value = args[0]; - if (nargs < 2) { - goto skip_optional; - } - if (!PyUnicode_Check(args[1])) { - _PyArg_BadArgument("format", "argument 2", "str", args[1]); - goto exit; - } - if (PyUnicode_READY(args[1]) == -1) { - goto exit; - } - format_spec = args[1]; -skip_optional: - return_value = builtin_format_impl(module, value, format_spec); - -exit: - return return_value; -} - -PyDoc_STRVAR(builtin_chr__doc__, -"chr($module, i, /)\n" -"--\n" -"\n" -"Return a Unicode string of one character with ordinal i; 0 <= i <= 0x10ffff."); - -#define BUILTIN_CHR_METHODDEF \ - {"chr", (PyCFunction)builtin_chr, METH_O, builtin_chr__doc__}, - -static PyObject * -builtin_chr_impl(PyObject *module, int i); - -static PyObject * -builtin_chr(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - int i; - - i = _PyLong_AsInt(arg); - if (i == -1 && PyErr_Occurred()) { - goto exit; - } - return_value = builtin_chr_impl(module, i); - -exit: - return return_value; -} - -PyDoc_STRVAR(builtin_compile__doc__, -"compile($module, /, source, filename, mode, flags=0,\n" -" dont_inherit=False, optimize=-1, *, _feature_version=-1)\n" -"--\n" -"\n" -"Compile source into a code object that can be executed by exec() or eval().\n" -"\n" -"The source code may represent a Python module, statement or expression.\n" -"The filename will be used for run-time error messages.\n" -"The mode must be \'exec\' to compile a module, \'single\' to compile a\n" -"single (interactive) statement, or \'eval\' to compile an expression.\n" -"The flags argument, if present, controls which future statements influence\n" -"the compilation of the code.\n" -"The dont_inherit argument, if true, stops the compilation inheriting\n" -"the effects of any future statements in effect in the code calling\n" -"compile; if absent or false these statements do influence the compilation,\n" -"in addition to any features explicitly specified."); - -#define BUILTIN_COMPILE_METHODDEF \ - {"compile", (PyCFunction)(void(*)(void))builtin_compile, METH_FASTCALL|METH_KEYWORDS, builtin_compile__doc__}, - -static PyObject * -builtin_compile_impl(PyObject *module, PyObject *source, PyObject *filename, - const char *mode, int flags, int dont_inherit, - int optimize, int feature_version); - -static PyObject * -builtin_compile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"source", "filename", "mode", "flags", "dont_inherit", "optimize", "_feature_version", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "compile", 0}; - PyObject *argsbuf[7]; - Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3; - PyObject *source; - PyObject *filename; - const char *mode; - int flags = 0; - int dont_inherit = 0; - int optimize = -1; - int feature_version = -1; - - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 3, 6, 0, argsbuf); - if (!args) { - goto exit; - } - source = args[0]; - if (!PyUnicode_FSDecoder(args[1], &filename)) { - goto exit; - } - if (!PyUnicode_Check(args[2])) { - _PyArg_BadArgument("compile", "argument 'mode'", "str", args[2]); - goto exit; - } - Py_ssize_t mode_length; - mode = PyUnicode_AsUTF8AndSize(args[2], &mode_length); - if (mode == NULL) { - goto exit; - } - if (strlen(mode) != (size_t)mode_length) { - PyErr_SetString(PyExc_ValueError, "embedded null character"); - goto exit; - } - if (!noptargs) { - goto skip_optional_pos; - } - if (args[3]) { - flags = _PyLong_AsInt(args[3]); - if (flags == -1 && PyErr_Occurred()) { - goto exit; - } - if (!--noptargs) { - goto skip_optional_pos; - } - } - if (args[4]) { - dont_inherit = _PyLong_AsInt(args[4]); - if (dont_inherit == -1 && PyErr_Occurred()) { - goto exit; - } - if (!--noptargs) { - goto skip_optional_pos; - } - } - if (args[5]) { - optimize = _PyLong_AsInt(args[5]); - if (optimize == -1 && PyErr_Occurred()) { - goto exit; - } - if (!--noptargs) { - goto skip_optional_pos; - } - } -skip_optional_pos: - if (!noptargs) { - goto skip_optional_kwonly; - } - feature_version = _PyLong_AsInt(args[6]); - if (feature_version == -1 && PyErr_Occurred()) { - goto exit; - } -skip_optional_kwonly: - return_value = builtin_compile_impl(module, source, filename, mode, flags, dont_inherit, optimize, feature_version); - -exit: - return return_value; -} - -PyDoc_STRVAR(builtin_divmod__doc__, -"divmod($module, x, y, /)\n" -"--\n" -"\n" -"Return the tuple (x//y, x%y). Invariant: div*y + mod == x."); - -#define BUILTIN_DIVMOD_METHODDEF \ - {"divmod", (PyCFunction)(void(*)(void))builtin_divmod, METH_FASTCALL, builtin_divmod__doc__}, - -static PyObject * -builtin_divmod_impl(PyObject *module, PyObject *x, PyObject *y); - -static PyObject * -builtin_divmod(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *x; - PyObject *y; - - if (!_PyArg_CheckPositional("divmod", nargs, 2, 2)) { - goto exit; - } - x = args[0]; - y = args[1]; - return_value = builtin_divmod_impl(module, x, y); - -exit: - return return_value; -} - -PyDoc_STRVAR(builtin_eval__doc__, -"eval($module, source, globals=None, locals=None, /)\n" -"--\n" -"\n" -"Evaluate the given source in the context of globals and locals.\n" -"\n" -"The source may be a string representing a Python expression\n" -"or a code object as returned by compile().\n" -"The globals must be a dictionary and locals can be any mapping,\n" -"defaulting to the current globals and locals.\n" -"If only globals is given, locals defaults to it."); - -#define BUILTIN_EVAL_METHODDEF \ - {"eval", (PyCFunction)(void(*)(void))builtin_eval, METH_FASTCALL, builtin_eval__doc__}, - -static PyObject * -builtin_eval_impl(PyObject *module, PyObject *source, PyObject *globals, - PyObject *locals); - -static PyObject * -builtin_eval(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *source; - PyObject *globals = Py_None; - PyObject *locals = Py_None; - - if (!_PyArg_CheckPositional("eval", nargs, 1, 3)) { - goto exit; - } - source = args[0]; - if (nargs < 2) { - goto skip_optional; - } - globals = args[1]; - if (nargs < 3) { - goto skip_optional; - } - locals = args[2]; -skip_optional: - return_value = builtin_eval_impl(module, source, globals, locals); - -exit: - return return_value; -} - -PyDoc_STRVAR(builtin_exec__doc__, -"exec($module, source, globals=None, locals=None, /)\n" -"--\n" -"\n" -"Execute the given source in the context of globals and locals.\n" -"\n" -"The source may be a string representing one or more Python statements\n" -"or a code object as returned by compile().\n" -"The globals must be a dictionary and locals can be any mapping,\n" -"defaulting to the current globals and locals.\n" -"If only globals is given, locals defaults to it."); - -#define BUILTIN_EXEC_METHODDEF \ - {"exec", (PyCFunction)(void(*)(void))builtin_exec, METH_FASTCALL, builtin_exec__doc__}, - -static PyObject * -builtin_exec_impl(PyObject *module, PyObject *source, PyObject *globals, - PyObject *locals); - -static PyObject * -builtin_exec(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *source; - PyObject *globals = Py_None; - PyObject *locals = Py_None; - - if (!_PyArg_CheckPositional("exec", nargs, 1, 3)) { - goto exit; - } - source = args[0]; - if (nargs < 2) { - goto skip_optional; - } - globals = args[1]; - if (nargs < 3) { - goto skip_optional; - } - locals = args[2]; -skip_optional: - return_value = builtin_exec_impl(module, source, globals, locals); - -exit: - return return_value; -} - -PyDoc_STRVAR(builtin_globals__doc__, -"globals($module, /)\n" -"--\n" -"\n" -"Return the dictionary containing the current scope\'s global variables.\n" -"\n" -"NOTE: Updates to this dictionary *will* affect name lookups in the current\n" -"global scope and vice-versa."); - -#define BUILTIN_GLOBALS_METHODDEF \ - {"globals", (PyCFunction)builtin_globals, METH_NOARGS, builtin_globals__doc__}, - -static PyObject * -builtin_globals_impl(PyObject *module); - -static PyObject * -builtin_globals(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return builtin_globals_impl(module); -} - -PyDoc_STRVAR(builtin_hasattr__doc__, -"hasattr($module, obj, name, /)\n" -"--\n" -"\n" -"Return whether the object has an attribute with the given name.\n" -"\n" -"This is done by calling getattr(obj, name) and catching AttributeError."); - -#define BUILTIN_HASATTR_METHODDEF \ - {"hasattr", (PyCFunction)(void(*)(void))builtin_hasattr, METH_FASTCALL, builtin_hasattr__doc__}, - -static PyObject * -builtin_hasattr_impl(PyObject *module, PyObject *obj, PyObject *name); - -static PyObject * -builtin_hasattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *obj; - PyObject *name; - - if (!_PyArg_CheckPositional("hasattr", nargs, 2, 2)) { - goto exit; - } - obj = args[0]; - name = args[1]; - return_value = builtin_hasattr_impl(module, obj, name); - -exit: - return return_value; -} - -PyDoc_STRVAR(builtin_id__doc__, -"id($module, obj, /)\n" -"--\n" -"\n" -"Return the identity of an object.\n" -"\n" -"This is guaranteed to be unique among simultaneously existing objects.\n" -"(CPython uses the object\'s memory address.)"); - -#define BUILTIN_ID_METHODDEF \ - {"id", (PyCFunction)builtin_id, METH_O, builtin_id__doc__}, - -PyDoc_STRVAR(builtin_setattr__doc__, -"setattr($module, obj, name, value, /)\n" -"--\n" -"\n" -"Sets the named attribute on the given object to the specified value.\n" -"\n" -"setattr(x, \'y\', v) is equivalent to ``x.y = v\'\'"); - -#define BUILTIN_SETATTR_METHODDEF \ - {"setattr", (PyCFunction)(void(*)(void))builtin_setattr, METH_FASTCALL, builtin_setattr__doc__}, - -static PyObject * -builtin_setattr_impl(PyObject *module, PyObject *obj, PyObject *name, - PyObject *value); - -static PyObject * -builtin_setattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *obj; - PyObject *name; - PyObject *value; - - if (!_PyArg_CheckPositional("setattr", nargs, 3, 3)) { - goto exit; - } - obj = args[0]; - name = args[1]; - value = args[2]; - return_value = builtin_setattr_impl(module, obj, name, value); - -exit: - return return_value; -} - -PyDoc_STRVAR(builtin_delattr__doc__, -"delattr($module, obj, name, /)\n" -"--\n" -"\n" -"Deletes the named attribute from the given object.\n" -"\n" -"delattr(x, \'y\') is equivalent to ``del x.y\'\'"); - -#define BUILTIN_DELATTR_METHODDEF \ - {"delattr", (PyCFunction)(void(*)(void))builtin_delattr, METH_FASTCALL, builtin_delattr__doc__}, - -static PyObject * -builtin_delattr_impl(PyObject *module, PyObject *obj, PyObject *name); - -static PyObject * -builtin_delattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *obj; - PyObject *name; - - if (!_PyArg_CheckPositional("delattr", nargs, 2, 2)) { - goto exit; - } - obj = args[0]; - name = args[1]; - return_value = builtin_delattr_impl(module, obj, name); - -exit: - return return_value; -} - -PyDoc_STRVAR(builtin_hash__doc__, -"hash($module, obj, /)\n" -"--\n" -"\n" -"Return the hash value for the given object.\n" -"\n" -"Two objects that compare equal must also have the same hash value, but the\n" -"reverse is not necessarily true."); - -#define BUILTIN_HASH_METHODDEF \ - {"hash", (PyCFunction)builtin_hash, METH_O, builtin_hash__doc__}, - -PyDoc_STRVAR(builtin_hex__doc__, -"hex($module, number, /)\n" -"--\n" -"\n" -"Return the hexadecimal representation of an integer.\n" -"\n" -" >>> hex(12648430)\n" -" \'0xc0ffee\'"); - -#define BUILTIN_HEX_METHODDEF \ - {"hex", (PyCFunction)builtin_hex, METH_O, builtin_hex__doc__}, - -PyDoc_STRVAR(builtin_aiter__doc__, -"aiter($module, async_iterable, /)\n" -"--\n" -"\n" -"Return an AsyncIterator for an AsyncIterable object."); - -#define BUILTIN_AITER_METHODDEF \ - {"aiter", (PyCFunction)builtin_aiter, METH_O, builtin_aiter__doc__}, - -PyDoc_STRVAR(builtin_anext__doc__, -"anext($module, aiterator, default=<unrepresentable>, /)\n" -"--\n" -"\n" -"Return the next item from the async iterator."); - -#define BUILTIN_ANEXT_METHODDEF \ - {"anext", (PyCFunction)(void(*)(void))builtin_anext, METH_FASTCALL, builtin_anext__doc__}, - -static PyObject * -builtin_anext_impl(PyObject *module, PyObject *aiterator, - PyObject *default_value); - -static PyObject * -builtin_anext(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *aiterator; - PyObject *default_value = NULL; - - if (!_PyArg_CheckPositional("anext", nargs, 1, 2)) { - goto exit; - } - aiterator = args[0]; - if (nargs < 2) { - goto skip_optional; - } - default_value = args[1]; -skip_optional: - return_value = builtin_anext_impl(module, aiterator, default_value); - -exit: - return return_value; -} - -PyDoc_STRVAR(builtin_len__doc__, -"len($module, obj, /)\n" -"--\n" -"\n" -"Return the number of items in a container."); - -#define BUILTIN_LEN_METHODDEF \ - {"len", (PyCFunction)builtin_len, METH_O, builtin_len__doc__}, - -PyDoc_STRVAR(builtin_locals__doc__, -"locals($module, /)\n" -"--\n" -"\n" -"Return a dictionary containing the current scope\'s local variables.\n" -"\n" -"NOTE: Whether or not updates to this dictionary will affect name lookups in\n" -"the local scope and vice-versa is *implementation dependent* and not\n" -"covered by any backwards compatibility guarantees."); - -#define BUILTIN_LOCALS_METHODDEF \ - {"locals", (PyCFunction)builtin_locals, METH_NOARGS, builtin_locals__doc__}, - -static PyObject * -builtin_locals_impl(PyObject *module); - -static PyObject * -builtin_locals(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return builtin_locals_impl(module); -} - -PyDoc_STRVAR(builtin_oct__doc__, -"oct($module, number, /)\n" -"--\n" -"\n" -"Return the octal representation of an integer.\n" -"\n" -" >>> oct(342391)\n" -" \'0o1234567\'"); - -#define BUILTIN_OCT_METHODDEF \ - {"oct", (PyCFunction)builtin_oct, METH_O, builtin_oct__doc__}, - -PyDoc_STRVAR(builtin_ord__doc__, -"ord($module, c, /)\n" -"--\n" -"\n" -"Return the Unicode code point for a one-character string."); - -#define BUILTIN_ORD_METHODDEF \ - {"ord", (PyCFunction)builtin_ord, METH_O, builtin_ord__doc__}, - -PyDoc_STRVAR(builtin_pow__doc__, -"pow($module, /, base, exp, mod=None)\n" -"--\n" -"\n" -"Equivalent to base**exp with 2 arguments or base**exp % mod with 3 arguments\n" -"\n" -"Some types, such as ints, are able to use a more efficient algorithm when\n" -"invoked using the three argument form."); - -#define BUILTIN_POW_METHODDEF \ - {"pow", (PyCFunction)(void(*)(void))builtin_pow, METH_FASTCALL|METH_KEYWORDS, builtin_pow__doc__}, - -static PyObject * -builtin_pow_impl(PyObject *module, PyObject *base, PyObject *exp, - PyObject *mod); - -static PyObject * -builtin_pow(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"base", "exp", "mod", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "pow", 0}; - PyObject *argsbuf[3]; - Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; - PyObject *base; - PyObject *exp; - PyObject *mod = Py_None; - - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 3, 0, argsbuf); - if (!args) { - goto exit; - } - base = args[0]; - exp = args[1]; - if (!noptargs) { - goto skip_optional_pos; - } - mod = args[2]; -skip_optional_pos: - return_value = builtin_pow_impl(module, base, exp, mod); - -exit: - return return_value; -} - -PyDoc_STRVAR(builtin_input__doc__, -"input($module, prompt=None, /)\n" -"--\n" -"\n" -"Read a string from standard input. The trailing newline is stripped.\n" -"\n" -"The prompt string, if given, is printed to standard output without a\n" -"trailing newline before reading input.\n" -"\n" -"If the user hits EOF (*nix: Ctrl-D, Windows: Ctrl-Z+Return), raise EOFError.\n" -"On *nix systems, readline is used if available."); - -#define BUILTIN_INPUT_METHODDEF \ - {"input", (PyCFunction)(void(*)(void))builtin_input, METH_FASTCALL, builtin_input__doc__}, - -static PyObject * -builtin_input_impl(PyObject *module, PyObject *prompt); - -static PyObject * -builtin_input(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *prompt = NULL; - - if (!_PyArg_CheckPositional("input", nargs, 0, 1)) { - goto exit; - } - if (nargs < 1) { - goto skip_optional; - } - prompt = args[0]; -skip_optional: - return_value = builtin_input_impl(module, prompt); - -exit: - return return_value; -} - -PyDoc_STRVAR(builtin_repr__doc__, -"repr($module, obj, /)\n" -"--\n" -"\n" -"Return the canonical string representation of the object.\n" -"\n" -"For many object types, including most builtins, eval(repr(obj)) == obj."); - -#define BUILTIN_REPR_METHODDEF \ - {"repr", (PyCFunction)builtin_repr, METH_O, builtin_repr__doc__}, - -PyDoc_STRVAR(builtin_round__doc__, -"round($module, /, number, ndigits=None)\n" -"--\n" -"\n" -"Round a number to a given precision in decimal digits.\n" -"\n" -"The return value is an integer if ndigits is omitted or None. Otherwise\n" -"the return value has the same type as the number. ndigits may be negative."); - -#define BUILTIN_ROUND_METHODDEF \ - {"round", (PyCFunction)(void(*)(void))builtin_round, METH_FASTCALL|METH_KEYWORDS, builtin_round__doc__}, - -static PyObject * -builtin_round_impl(PyObject *module, PyObject *number, PyObject *ndigits); - -static PyObject * -builtin_round(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"number", "ndigits", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "round", 0}; - PyObject *argsbuf[2]; - Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - PyObject *number; - PyObject *ndigits = Py_None; - - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); - if (!args) { - goto exit; - } - number = args[0]; - if (!noptargs) { - goto skip_optional_pos; - } - ndigits = args[1]; -skip_optional_pos: - return_value = builtin_round_impl(module, number, ndigits); - -exit: - return return_value; -} - -PyDoc_STRVAR(builtin_sum__doc__, -"sum($module, iterable, /, start=0)\n" -"--\n" -"\n" -"Return the sum of a \'start\' value (default: 0) plus an iterable of numbers\n" -"\n" -"When the iterable is empty, return the start value.\n" -"This function is intended specifically for use with numeric values and may\n" -"reject non-numeric types."); - -#define BUILTIN_SUM_METHODDEF \ - {"sum", (PyCFunction)(void(*)(void))builtin_sum, METH_FASTCALL|METH_KEYWORDS, builtin_sum__doc__}, - -static PyObject * -builtin_sum_impl(PyObject *module, PyObject *iterable, PyObject *start); - -static PyObject * -builtin_sum(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"", "start", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "sum", 0}; - PyObject *argsbuf[2]; - Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - PyObject *iterable; - PyObject *start = NULL; - - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); - if (!args) { - goto exit; - } - iterable = args[0]; - if (!noptargs) { - goto skip_optional_pos; - } - start = args[1]; -skip_optional_pos: - return_value = builtin_sum_impl(module, iterable, start); - -exit: - return return_value; -} - -PyDoc_STRVAR(builtin_isinstance__doc__, -"isinstance($module, obj, class_or_tuple, /)\n" -"--\n" -"\n" -"Return whether an object is an instance of a class or of a subclass thereof.\n" -"\n" -"A tuple, as in ``isinstance(x, (A, B, ...))``, may be given as the target to\n" -"check against. This is equivalent to ``isinstance(x, A) or isinstance(x, B)\n" -"or ...`` etc."); - -#define BUILTIN_ISINSTANCE_METHODDEF \ - {"isinstance", (PyCFunction)(void(*)(void))builtin_isinstance, METH_FASTCALL, builtin_isinstance__doc__}, - -static PyObject * -builtin_isinstance_impl(PyObject *module, PyObject *obj, - PyObject *class_or_tuple); - -static PyObject * -builtin_isinstance(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *obj; - PyObject *class_or_tuple; - - if (!_PyArg_CheckPositional("isinstance", nargs, 2, 2)) { - goto exit; - } - obj = args[0]; - class_or_tuple = args[1]; - return_value = builtin_isinstance_impl(module, obj, class_or_tuple); - -exit: - return return_value; -} - -PyDoc_STRVAR(builtin_issubclass__doc__, -"issubclass($module, cls, class_or_tuple, /)\n" -"--\n" -"\n" -"Return whether \'cls\' is derived from another class or is the same class.\n" -"\n" -"A tuple, as in ``issubclass(x, (A, B, ...))``, may be given as the target to\n" -"check against. This is equivalent to ``issubclass(x, A) or issubclass(x, B)\n" -"or ...``."); - -#define BUILTIN_ISSUBCLASS_METHODDEF \ - {"issubclass", (PyCFunction)(void(*)(void))builtin_issubclass, METH_FASTCALL, builtin_issubclass__doc__}, - -static PyObject * -builtin_issubclass_impl(PyObject *module, PyObject *cls, - PyObject *class_or_tuple); - -static PyObject * -builtin_issubclass(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *cls; - PyObject *class_or_tuple; - - if (!_PyArg_CheckPositional("issubclass", nargs, 2, 2)) { - goto exit; - } - cls = args[0]; - class_or_tuple = args[1]; - return_value = builtin_issubclass_impl(module, cls, class_or_tuple); - -exit: - return return_value; -} -/*[clinic end generated code: output=da9ae459e9233259 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Python/clinic/context.c.h b/contrib/tools/python3/src/Python/clinic/context.c.h deleted file mode 100644 index 2ac8bf7c0b8..00000000000 --- a/contrib/tools/python3/src/Python/clinic/context.c.h +++ /dev/null @@ -1,180 +0,0 @@ -/*[clinic input] -preserve -[clinic start generated code]*/ - -PyDoc_STRVAR(_contextvars_Context_get__doc__, -"get($self, key, default=None, /)\n" -"--\n" -"\n" -"Return the value for `key` if `key` has the value in the context object.\n" -"\n" -"If `key` does not exist, return `default`. If `default` is not given,\n" -"return None."); - -#define _CONTEXTVARS_CONTEXT_GET_METHODDEF \ - {"get", (PyCFunction)(void(*)(void))_contextvars_Context_get, METH_FASTCALL, _contextvars_Context_get__doc__}, - -static PyObject * -_contextvars_Context_get_impl(PyContext *self, PyObject *key, - PyObject *default_value); - -static PyObject * -_contextvars_Context_get(PyContext *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *key; - PyObject *default_value = Py_None; - - if (!_PyArg_CheckPositional("get", nargs, 1, 2)) { - goto exit; - } - key = args[0]; - if (nargs < 2) { - goto skip_optional; - } - default_value = args[1]; -skip_optional: - return_value = _contextvars_Context_get_impl(self, key, default_value); - -exit: - return return_value; -} - -PyDoc_STRVAR(_contextvars_Context_items__doc__, -"items($self, /)\n" -"--\n" -"\n" -"Return all variables and their values in the context object.\n" -"\n" -"The result is returned as a list of 2-tuples (variable, value)."); - -#define _CONTEXTVARS_CONTEXT_ITEMS_METHODDEF \ - {"items", (PyCFunction)_contextvars_Context_items, METH_NOARGS, _contextvars_Context_items__doc__}, - -static PyObject * -_contextvars_Context_items_impl(PyContext *self); - -static PyObject * -_contextvars_Context_items(PyContext *self, PyObject *Py_UNUSED(ignored)) -{ - return _contextvars_Context_items_impl(self); -} - -PyDoc_STRVAR(_contextvars_Context_keys__doc__, -"keys($self, /)\n" -"--\n" -"\n" -"Return a list of all variables in the context object."); - -#define _CONTEXTVARS_CONTEXT_KEYS_METHODDEF \ - {"keys", (PyCFunction)_contextvars_Context_keys, METH_NOARGS, _contextvars_Context_keys__doc__}, - -static PyObject * -_contextvars_Context_keys_impl(PyContext *self); - -static PyObject * -_contextvars_Context_keys(PyContext *self, PyObject *Py_UNUSED(ignored)) -{ - return _contextvars_Context_keys_impl(self); -} - -PyDoc_STRVAR(_contextvars_Context_values__doc__, -"values($self, /)\n" -"--\n" -"\n" -"Return a list of all variables\' values in the context object."); - -#define _CONTEXTVARS_CONTEXT_VALUES_METHODDEF \ - {"values", (PyCFunction)_contextvars_Context_values, METH_NOARGS, _contextvars_Context_values__doc__}, - -static PyObject * -_contextvars_Context_values_impl(PyContext *self); - -static PyObject * -_contextvars_Context_values(PyContext *self, PyObject *Py_UNUSED(ignored)) -{ - return _contextvars_Context_values_impl(self); -} - -PyDoc_STRVAR(_contextvars_Context_copy__doc__, -"copy($self, /)\n" -"--\n" -"\n" -"Return a shallow copy of the context object."); - -#define _CONTEXTVARS_CONTEXT_COPY_METHODDEF \ - {"copy", (PyCFunction)_contextvars_Context_copy, METH_NOARGS, _contextvars_Context_copy__doc__}, - -static PyObject * -_contextvars_Context_copy_impl(PyContext *self); - -static PyObject * -_contextvars_Context_copy(PyContext *self, PyObject *Py_UNUSED(ignored)) -{ - return _contextvars_Context_copy_impl(self); -} - -PyDoc_STRVAR(_contextvars_ContextVar_get__doc__, -"get($self, default=<unrepresentable>, /)\n" -"--\n" -"\n" -"Return a value for the context variable for the current context.\n" -"\n" -"If there is no value for the variable in the current context, the method will:\n" -" * return the value of the default argument of the method, if provided; or\n" -" * return the default value for the context variable, if it was created\n" -" with one; or\n" -" * raise a LookupError."); - -#define _CONTEXTVARS_CONTEXTVAR_GET_METHODDEF \ - {"get", (PyCFunction)(void(*)(void))_contextvars_ContextVar_get, METH_FASTCALL, _contextvars_ContextVar_get__doc__}, - -static PyObject * -_contextvars_ContextVar_get_impl(PyContextVar *self, PyObject *default_value); - -static PyObject * -_contextvars_ContextVar_get(PyContextVar *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *default_value = NULL; - - if (!_PyArg_CheckPositional("get", nargs, 0, 1)) { - goto exit; - } - if (nargs < 1) { - goto skip_optional; - } - default_value = args[0]; -skip_optional: - return_value = _contextvars_ContextVar_get_impl(self, default_value); - -exit: - return return_value; -} - -PyDoc_STRVAR(_contextvars_ContextVar_set__doc__, -"set($self, value, /)\n" -"--\n" -"\n" -"Call to set a new value for the context variable in the current context.\n" -"\n" -"The required value argument is the new value for the context variable.\n" -"\n" -"Returns a Token object that can be used to restore the variable to its previous\n" -"value via the `ContextVar.reset()` method."); - -#define _CONTEXTVARS_CONTEXTVAR_SET_METHODDEF \ - {"set", (PyCFunction)_contextvars_ContextVar_set, METH_O, _contextvars_ContextVar_set__doc__}, - -PyDoc_STRVAR(_contextvars_ContextVar_reset__doc__, -"reset($self, token, /)\n" -"--\n" -"\n" -"Reset the context variable.\n" -"\n" -"The variable is reset to the value it had before the `ContextVar.set()` that\n" -"created the token was used."); - -#define _CONTEXTVARS_CONTEXTVAR_RESET_METHODDEF \ - {"reset", (PyCFunction)_contextvars_ContextVar_reset, METH_O, _contextvars_ContextVar_reset__doc__}, -/*[clinic end generated code: output=f2e42f34e358e179 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Python/clinic/import.c.h b/contrib/tools/python3/src/Python/clinic/import.c.h deleted file mode 100644 index 4e013cc97d6..00000000000 --- a/contrib/tools/python3/src/Python/clinic/import.c.h +++ /dev/null @@ -1,452 +0,0 @@ -/*[clinic input] -preserve -[clinic start generated code]*/ - -PyDoc_STRVAR(_imp_lock_held__doc__, -"lock_held($module, /)\n" -"--\n" -"\n" -"Return True if the import lock is currently held, else False.\n" -"\n" -"On platforms without threads, return False."); - -#define _IMP_LOCK_HELD_METHODDEF \ - {"lock_held", (PyCFunction)_imp_lock_held, METH_NOARGS, _imp_lock_held__doc__}, - -static PyObject * -_imp_lock_held_impl(PyObject *module); - -static PyObject * -_imp_lock_held(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return _imp_lock_held_impl(module); -} - -PyDoc_STRVAR(_imp_acquire_lock__doc__, -"acquire_lock($module, /)\n" -"--\n" -"\n" -"Acquires the interpreter\'s import lock for the current thread.\n" -"\n" -"This lock should be used by import hooks to ensure thread-safety when importing\n" -"modules. On platforms without threads, this function does nothing."); - -#define _IMP_ACQUIRE_LOCK_METHODDEF \ - {"acquire_lock", (PyCFunction)_imp_acquire_lock, METH_NOARGS, _imp_acquire_lock__doc__}, - -static PyObject * -_imp_acquire_lock_impl(PyObject *module); - -static PyObject * -_imp_acquire_lock(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return _imp_acquire_lock_impl(module); -} - -PyDoc_STRVAR(_imp_release_lock__doc__, -"release_lock($module, /)\n" -"--\n" -"\n" -"Release the interpreter\'s import lock.\n" -"\n" -"On platforms without threads, this function does nothing."); - -#define _IMP_RELEASE_LOCK_METHODDEF \ - {"release_lock", (PyCFunction)_imp_release_lock, METH_NOARGS, _imp_release_lock__doc__}, - -static PyObject * -_imp_release_lock_impl(PyObject *module); - -static PyObject * -_imp_release_lock(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return _imp_release_lock_impl(module); -} - -PyDoc_STRVAR(_imp__fix_co_filename__doc__, -"_fix_co_filename($module, code, path, /)\n" -"--\n" -"\n" -"Changes code.co_filename to specify the passed-in file path.\n" -"\n" -" code\n" -" Code object to change.\n" -" path\n" -" File path to use."); - -#define _IMP__FIX_CO_FILENAME_METHODDEF \ - {"_fix_co_filename", (PyCFunction)(void(*)(void))_imp__fix_co_filename, METH_FASTCALL, _imp__fix_co_filename__doc__}, - -static PyObject * -_imp__fix_co_filename_impl(PyObject *module, PyCodeObject *code, - PyObject *path); - -static PyObject * -_imp__fix_co_filename(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyCodeObject *code; - PyObject *path; - - if (!_PyArg_CheckPositional("_fix_co_filename", nargs, 2, 2)) { - goto exit; - } - if (!PyObject_TypeCheck(args[0], &PyCode_Type)) { - _PyArg_BadArgument("_fix_co_filename", "argument 1", (&PyCode_Type)->tp_name, args[0]); - goto exit; - } - code = (PyCodeObject *)args[0]; - if (!PyUnicode_Check(args[1])) { - _PyArg_BadArgument("_fix_co_filename", "argument 2", "str", args[1]); - goto exit; - } - if (PyUnicode_READY(args[1]) == -1) { - goto exit; - } - path = args[1]; - return_value = _imp__fix_co_filename_impl(module, code, path); - -exit: - return return_value; -} - -PyDoc_STRVAR(_imp_create_builtin__doc__, -"create_builtin($module, spec, /)\n" -"--\n" -"\n" -"Create an extension module."); - -#define _IMP_CREATE_BUILTIN_METHODDEF \ - {"create_builtin", (PyCFunction)_imp_create_builtin, METH_O, _imp_create_builtin__doc__}, - -PyDoc_STRVAR(_imp_extension_suffixes__doc__, -"extension_suffixes($module, /)\n" -"--\n" -"\n" -"Returns the list of file suffixes used to identify extension modules."); - -#define _IMP_EXTENSION_SUFFIXES_METHODDEF \ - {"extension_suffixes", (PyCFunction)_imp_extension_suffixes, METH_NOARGS, _imp_extension_suffixes__doc__}, - -static PyObject * -_imp_extension_suffixes_impl(PyObject *module); - -static PyObject * -_imp_extension_suffixes(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return _imp_extension_suffixes_impl(module); -} - -PyDoc_STRVAR(_imp_init_frozen__doc__, -"init_frozen($module, name, /)\n" -"--\n" -"\n" -"Initializes a frozen module."); - -#define _IMP_INIT_FROZEN_METHODDEF \ - {"init_frozen", (PyCFunction)_imp_init_frozen, METH_O, _imp_init_frozen__doc__}, - -static PyObject * -_imp_init_frozen_impl(PyObject *module, PyObject *name); - -static PyObject * -_imp_init_frozen(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - PyObject *name; - - if (!PyUnicode_Check(arg)) { - _PyArg_BadArgument("init_frozen", "argument", "str", arg); - goto exit; - } - if (PyUnicode_READY(arg) == -1) { - goto exit; - } - name = arg; - return_value = _imp_init_frozen_impl(module, name); - -exit: - return return_value; -} - -PyDoc_STRVAR(_imp_get_frozen_object__doc__, -"get_frozen_object($module, name, /)\n" -"--\n" -"\n" -"Create a code object for a frozen module."); - -#define _IMP_GET_FROZEN_OBJECT_METHODDEF \ - {"get_frozen_object", (PyCFunction)_imp_get_frozen_object, METH_O, _imp_get_frozen_object__doc__}, - -static PyObject * -_imp_get_frozen_object_impl(PyObject *module, PyObject *name); - -static PyObject * -_imp_get_frozen_object(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - PyObject *name; - - if (!PyUnicode_Check(arg)) { - _PyArg_BadArgument("get_frozen_object", "argument", "str", arg); - goto exit; - } - if (PyUnicode_READY(arg) == -1) { - goto exit; - } - name = arg; - return_value = _imp_get_frozen_object_impl(module, name); - -exit: - return return_value; -} - -PyDoc_STRVAR(_imp_is_frozen_package__doc__, -"is_frozen_package($module, name, /)\n" -"--\n" -"\n" -"Returns True if the module name is of a frozen package."); - -#define _IMP_IS_FROZEN_PACKAGE_METHODDEF \ - {"is_frozen_package", (PyCFunction)_imp_is_frozen_package, METH_O, _imp_is_frozen_package__doc__}, - -static PyObject * -_imp_is_frozen_package_impl(PyObject *module, PyObject *name); - -static PyObject * -_imp_is_frozen_package(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - PyObject *name; - - if (!PyUnicode_Check(arg)) { - _PyArg_BadArgument("is_frozen_package", "argument", "str", arg); - goto exit; - } - if (PyUnicode_READY(arg) == -1) { - goto exit; - } - name = arg; - return_value = _imp_is_frozen_package_impl(module, name); - -exit: - return return_value; -} - -PyDoc_STRVAR(_imp_is_builtin__doc__, -"is_builtin($module, name, /)\n" -"--\n" -"\n" -"Returns True if the module name corresponds to a built-in module."); - -#define _IMP_IS_BUILTIN_METHODDEF \ - {"is_builtin", (PyCFunction)_imp_is_builtin, METH_O, _imp_is_builtin__doc__}, - -static PyObject * -_imp_is_builtin_impl(PyObject *module, PyObject *name); - -static PyObject * -_imp_is_builtin(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - PyObject *name; - - if (!PyUnicode_Check(arg)) { - _PyArg_BadArgument("is_builtin", "argument", "str", arg); - goto exit; - } - if (PyUnicode_READY(arg) == -1) { - goto exit; - } - name = arg; - return_value = _imp_is_builtin_impl(module, name); - -exit: - return return_value; -} - -PyDoc_STRVAR(_imp_is_frozen__doc__, -"is_frozen($module, name, /)\n" -"--\n" -"\n" -"Returns True if the module name corresponds to a frozen module."); - -#define _IMP_IS_FROZEN_METHODDEF \ - {"is_frozen", (PyCFunction)_imp_is_frozen, METH_O, _imp_is_frozen__doc__}, - -static PyObject * -_imp_is_frozen_impl(PyObject *module, PyObject *name); - -static PyObject * -_imp_is_frozen(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - PyObject *name; - - if (!PyUnicode_Check(arg)) { - _PyArg_BadArgument("is_frozen", "argument", "str", arg); - goto exit; - } - if (PyUnicode_READY(arg) == -1) { - goto exit; - } - name = arg; - return_value = _imp_is_frozen_impl(module, name); - -exit: - return return_value; -} - -#if defined(HAVE_DYNAMIC_LOADING) - -PyDoc_STRVAR(_imp_create_dynamic__doc__, -"create_dynamic($module, spec, file=<unrepresentable>, /)\n" -"--\n" -"\n" -"Create an extension module."); - -#define _IMP_CREATE_DYNAMIC_METHODDEF \ - {"create_dynamic", (PyCFunction)(void(*)(void))_imp_create_dynamic, METH_FASTCALL, _imp_create_dynamic__doc__}, - -static PyObject * -_imp_create_dynamic_impl(PyObject *module, PyObject *spec, PyObject *file); - -static PyObject * -_imp_create_dynamic(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *spec; - PyObject *file = NULL; - - if (!_PyArg_CheckPositional("create_dynamic", nargs, 1, 2)) { - goto exit; - } - spec = args[0]; - if (nargs < 2) { - goto skip_optional; - } - file = args[1]; -skip_optional: - return_value = _imp_create_dynamic_impl(module, spec, file); - -exit: - return return_value; -} - -#endif /* defined(HAVE_DYNAMIC_LOADING) */ - -#if defined(HAVE_DYNAMIC_LOADING) - -PyDoc_STRVAR(_imp_exec_dynamic__doc__, -"exec_dynamic($module, mod, /)\n" -"--\n" -"\n" -"Initialize an extension module."); - -#define _IMP_EXEC_DYNAMIC_METHODDEF \ - {"exec_dynamic", (PyCFunction)_imp_exec_dynamic, METH_O, _imp_exec_dynamic__doc__}, - -static int -_imp_exec_dynamic_impl(PyObject *module, PyObject *mod); - -static PyObject * -_imp_exec_dynamic(PyObject *module, PyObject *mod) -{ - PyObject *return_value = NULL; - int _return_value; - - _return_value = _imp_exec_dynamic_impl(module, mod); - if ((_return_value == -1) && PyErr_Occurred()) { - goto exit; - } - return_value = PyLong_FromLong((long)_return_value); - -exit: - return return_value; -} - -#endif /* defined(HAVE_DYNAMIC_LOADING) */ - -PyDoc_STRVAR(_imp_exec_builtin__doc__, -"exec_builtin($module, mod, /)\n" -"--\n" -"\n" -"Initialize a built-in module."); - -#define _IMP_EXEC_BUILTIN_METHODDEF \ - {"exec_builtin", (PyCFunction)_imp_exec_builtin, METH_O, _imp_exec_builtin__doc__}, - -static int -_imp_exec_builtin_impl(PyObject *module, PyObject *mod); - -static PyObject * -_imp_exec_builtin(PyObject *module, PyObject *mod) -{ - PyObject *return_value = NULL; - int _return_value; - - _return_value = _imp_exec_builtin_impl(module, mod); - if ((_return_value == -1) && PyErr_Occurred()) { - goto exit; - } - return_value = PyLong_FromLong((long)_return_value); - -exit: - return return_value; -} - -PyDoc_STRVAR(_imp_source_hash__doc__, -"source_hash($module, /, key, source)\n" -"--\n" -"\n"); - -#define _IMP_SOURCE_HASH_METHODDEF \ - {"source_hash", (PyCFunction)(void(*)(void))_imp_source_hash, METH_FASTCALL|METH_KEYWORDS, _imp_source_hash__doc__}, - -static PyObject * -_imp_source_hash_impl(PyObject *module, long key, Py_buffer *source); - -static PyObject * -_imp_source_hash(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"key", "source", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "source_hash", 0}; - PyObject *argsbuf[2]; - long key; - Py_buffer source = {NULL, NULL}; - - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); - if (!args) { - goto exit; - } - key = PyLong_AsLong(args[0]); - if (key == -1 && PyErr_Occurred()) { - goto exit; - } - if (PyObject_GetBuffer(args[1], &source, PyBUF_SIMPLE) != 0) { - goto exit; - } - if (!PyBuffer_IsContiguous(&source, 'C')) { - _PyArg_BadArgument("source_hash", "argument 'source'", "contiguous buffer", args[1]); - goto exit; - } - return_value = _imp_source_hash_impl(module, key, &source); - -exit: - /* Cleanup for source */ - if (source.obj) { - PyBuffer_Release(&source); - } - - return return_value; -} - -#ifndef _IMP_CREATE_DYNAMIC_METHODDEF - #define _IMP_CREATE_DYNAMIC_METHODDEF -#endif /* !defined(_IMP_CREATE_DYNAMIC_METHODDEF) */ - -#ifndef _IMP_EXEC_DYNAMIC_METHODDEF - #define _IMP_EXEC_DYNAMIC_METHODDEF -#endif /* !defined(_IMP_EXEC_DYNAMIC_METHODDEF) */ -/*[clinic end generated code: output=7c31c433af88af6b input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Python/clinic/marshal.c.h b/contrib/tools/python3/src/Python/clinic/marshal.c.h deleted file mode 100644 index f80d5ef31f2..00000000000 --- a/contrib/tools/python3/src/Python/clinic/marshal.c.h +++ /dev/null @@ -1,158 +0,0 @@ -/*[clinic input] -preserve -[clinic start generated code]*/ - -PyDoc_STRVAR(marshal_dump__doc__, -"dump($module, value, file, version=version, /)\n" -"--\n" -"\n" -"Write the value on the open file.\n" -"\n" -" value\n" -" Must be a supported type.\n" -" file\n" -" Must be a writeable binary file.\n" -" version\n" -" Indicates the data format that dump should use.\n" -"\n" -"If the value has (or contains an object that has) an unsupported type, a\n" -"ValueError exception is raised - but garbage data will also be written\n" -"to the file. The object will not be properly read back by load()."); - -#define MARSHAL_DUMP_METHODDEF \ - {"dump", (PyCFunction)(void(*)(void))marshal_dump, METH_FASTCALL, marshal_dump__doc__}, - -static PyObject * -marshal_dump_impl(PyObject *module, PyObject *value, PyObject *file, - int version); - -static PyObject * -marshal_dump(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *value; - PyObject *file; - int version = Py_MARSHAL_VERSION; - - if (!_PyArg_CheckPositional("dump", nargs, 2, 3)) { - goto exit; - } - value = args[0]; - file = args[1]; - if (nargs < 3) { - goto skip_optional; - } - version = _PyLong_AsInt(args[2]); - if (version == -1 && PyErr_Occurred()) { - goto exit; - } -skip_optional: - return_value = marshal_dump_impl(module, value, file, version); - -exit: - return return_value; -} - -PyDoc_STRVAR(marshal_load__doc__, -"load($module, file, /)\n" -"--\n" -"\n" -"Read one value from the open file and return it.\n" -"\n" -" file\n" -" Must be readable binary file.\n" -"\n" -"If no valid value is read (e.g. because the data has a different Python\n" -"version\'s incompatible marshal format), raise EOFError, ValueError or\n" -"TypeError.\n" -"\n" -"Note: If an object containing an unsupported type was marshalled with\n" -"dump(), load() will substitute None for the unmarshallable type."); - -#define MARSHAL_LOAD_METHODDEF \ - {"load", (PyCFunction)marshal_load, METH_O, marshal_load__doc__}, - -PyDoc_STRVAR(marshal_dumps__doc__, -"dumps($module, value, version=version, /)\n" -"--\n" -"\n" -"Return the bytes object that would be written to a file by dump(value, file).\n" -"\n" -" value\n" -" Must be a supported type.\n" -" version\n" -" Indicates the data format that dumps should use.\n" -"\n" -"Raise a ValueError exception if value has (or contains an object that has) an\n" -"unsupported type."); - -#define MARSHAL_DUMPS_METHODDEF \ - {"dumps", (PyCFunction)(void(*)(void))marshal_dumps, METH_FASTCALL, marshal_dumps__doc__}, - -static PyObject * -marshal_dumps_impl(PyObject *module, PyObject *value, int version); - -static PyObject * -marshal_dumps(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *value; - int version = Py_MARSHAL_VERSION; - - if (!_PyArg_CheckPositional("dumps", nargs, 1, 2)) { - goto exit; - } - value = args[0]; - if (nargs < 2) { - goto skip_optional; - } - version = _PyLong_AsInt(args[1]); - if (version == -1 && PyErr_Occurred()) { - goto exit; - } -skip_optional: - return_value = marshal_dumps_impl(module, value, version); - -exit: - return return_value; -} - -PyDoc_STRVAR(marshal_loads__doc__, -"loads($module, bytes, /)\n" -"--\n" -"\n" -"Convert the bytes-like object to a value.\n" -"\n" -"If no valid value is found, raise EOFError, ValueError or TypeError. Extra\n" -"bytes in the input are ignored."); - -#define MARSHAL_LOADS_METHODDEF \ - {"loads", (PyCFunction)marshal_loads, METH_O, marshal_loads__doc__}, - -static PyObject * -marshal_loads_impl(PyObject *module, Py_buffer *bytes); - -static PyObject * -marshal_loads(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - Py_buffer bytes = {NULL, NULL}; - - if (PyObject_GetBuffer(arg, &bytes, PyBUF_SIMPLE) != 0) { - goto exit; - } - if (!PyBuffer_IsContiguous(&bytes, 'C')) { - _PyArg_BadArgument("loads", "argument", "contiguous buffer", arg); - goto exit; - } - return_value = marshal_loads_impl(module, &bytes); - -exit: - /* Cleanup for bytes */ - if (bytes.obj) { - PyBuffer_Release(&bytes); - } - - return return_value; -} -/*[clinic end generated code: output=68b78f38bfe0c06d input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Python/clinic/sysmodule.c.h b/contrib/tools/python3/src/Python/clinic/sysmodule.c.h deleted file mode 100644 index 04c84811498..00000000000 --- a/contrib/tools/python3/src/Python/clinic/sysmodule.c.h +++ /dev/null @@ -1,986 +0,0 @@ -/*[clinic input] -preserve -[clinic start generated code]*/ - -PyDoc_STRVAR(sys_addaudithook__doc__, -"addaudithook($module, /, hook)\n" -"--\n" -"\n" -"Adds a new audit hook callback."); - -#define SYS_ADDAUDITHOOK_METHODDEF \ - {"addaudithook", (PyCFunction)(void(*)(void))sys_addaudithook, METH_FASTCALL|METH_KEYWORDS, sys_addaudithook__doc__}, - -static PyObject * -sys_addaudithook_impl(PyObject *module, PyObject *hook); - -static PyObject * -sys_addaudithook(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"hook", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "addaudithook", 0}; - PyObject *argsbuf[1]; - PyObject *hook; - - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); - if (!args) { - goto exit; - } - hook = args[0]; - return_value = sys_addaudithook_impl(module, hook); - -exit: - return return_value; -} - -PyDoc_STRVAR(sys_displayhook__doc__, -"displayhook($module, object, /)\n" -"--\n" -"\n" -"Print an object to sys.stdout and also save it in builtins._"); - -#define SYS_DISPLAYHOOK_METHODDEF \ - {"displayhook", (PyCFunction)sys_displayhook, METH_O, sys_displayhook__doc__}, - -PyDoc_STRVAR(sys_excepthook__doc__, -"excepthook($module, exctype, value, traceback, /)\n" -"--\n" -"\n" -"Handle an exception by displaying it with a traceback on sys.stderr."); - -#define SYS_EXCEPTHOOK_METHODDEF \ - {"excepthook", (PyCFunction)(void(*)(void))sys_excepthook, METH_FASTCALL, sys_excepthook__doc__}, - -static PyObject * -sys_excepthook_impl(PyObject *module, PyObject *exctype, PyObject *value, - PyObject *traceback); - -static PyObject * -sys_excepthook(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *exctype; - PyObject *value; - PyObject *traceback; - - if (!_PyArg_CheckPositional("excepthook", nargs, 3, 3)) { - goto exit; - } - exctype = args[0]; - value = args[1]; - traceback = args[2]; - return_value = sys_excepthook_impl(module, exctype, value, traceback); - -exit: - return return_value; -} - -PyDoc_STRVAR(sys_exc_info__doc__, -"exc_info($module, /)\n" -"--\n" -"\n" -"Return current exception information: (type, value, traceback).\n" -"\n" -"Return information about the most recent exception caught by an except\n" -"clause in the current stack frame or in an older stack frame."); - -#define SYS_EXC_INFO_METHODDEF \ - {"exc_info", (PyCFunction)sys_exc_info, METH_NOARGS, sys_exc_info__doc__}, - -static PyObject * -sys_exc_info_impl(PyObject *module); - -static PyObject * -sys_exc_info(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return sys_exc_info_impl(module); -} - -PyDoc_STRVAR(sys_unraisablehook__doc__, -"unraisablehook($module, unraisable, /)\n" -"--\n" -"\n" -"Handle an unraisable exception.\n" -"\n" -"The unraisable argument has the following attributes:\n" -"\n" -"* exc_type: Exception type.\n" -"* exc_value: Exception value, can be None.\n" -"* exc_traceback: Exception traceback, can be None.\n" -"* err_msg: Error message, can be None.\n" -"* object: Object causing the exception, can be None."); - -#define SYS_UNRAISABLEHOOK_METHODDEF \ - {"unraisablehook", (PyCFunction)sys_unraisablehook, METH_O, sys_unraisablehook__doc__}, - -PyDoc_STRVAR(sys_exit__doc__, -"exit($module, status=None, /)\n" -"--\n" -"\n" -"Exit the interpreter by raising SystemExit(status).\n" -"\n" -"If the status is omitted or None, it defaults to zero (i.e., success).\n" -"If the status is an integer, it will be used as the system exit status.\n" -"If it is another kind of object, it will be printed and the system\n" -"exit status will be one (i.e., failure)."); - -#define SYS_EXIT_METHODDEF \ - {"exit", (PyCFunction)(void(*)(void))sys_exit, METH_FASTCALL, sys_exit__doc__}, - -static PyObject * -sys_exit_impl(PyObject *module, PyObject *status); - -static PyObject * -sys_exit(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *status = Py_None; - - if (!_PyArg_CheckPositional("exit", nargs, 0, 1)) { - goto exit; - } - if (nargs < 1) { - goto skip_optional; - } - status = args[0]; -skip_optional: - return_value = sys_exit_impl(module, status); - -exit: - return return_value; -} - -PyDoc_STRVAR(sys_getdefaultencoding__doc__, -"getdefaultencoding($module, /)\n" -"--\n" -"\n" -"Return the current default encoding used by the Unicode implementation."); - -#define SYS_GETDEFAULTENCODING_METHODDEF \ - {"getdefaultencoding", (PyCFunction)sys_getdefaultencoding, METH_NOARGS, sys_getdefaultencoding__doc__}, - -static PyObject * -sys_getdefaultencoding_impl(PyObject *module); - -static PyObject * -sys_getdefaultencoding(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return sys_getdefaultencoding_impl(module); -} - -PyDoc_STRVAR(sys_getfilesystemencoding__doc__, -"getfilesystemencoding($module, /)\n" -"--\n" -"\n" -"Return the encoding used to convert Unicode filenames to OS filenames."); - -#define SYS_GETFILESYSTEMENCODING_METHODDEF \ - {"getfilesystemencoding", (PyCFunction)sys_getfilesystemencoding, METH_NOARGS, sys_getfilesystemencoding__doc__}, - -static PyObject * -sys_getfilesystemencoding_impl(PyObject *module); - -static PyObject * -sys_getfilesystemencoding(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return sys_getfilesystemencoding_impl(module); -} - -PyDoc_STRVAR(sys_getfilesystemencodeerrors__doc__, -"getfilesystemencodeerrors($module, /)\n" -"--\n" -"\n" -"Return the error mode used Unicode to OS filename conversion."); - -#define SYS_GETFILESYSTEMENCODEERRORS_METHODDEF \ - {"getfilesystemencodeerrors", (PyCFunction)sys_getfilesystemencodeerrors, METH_NOARGS, sys_getfilesystemencodeerrors__doc__}, - -static PyObject * -sys_getfilesystemencodeerrors_impl(PyObject *module); - -static PyObject * -sys_getfilesystemencodeerrors(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return sys_getfilesystemencodeerrors_impl(module); -} - -PyDoc_STRVAR(sys_intern__doc__, -"intern($module, string, /)\n" -"--\n" -"\n" -"``Intern\'\' the given string.\n" -"\n" -"This enters the string in the (global) table of interned strings whose\n" -"purpose is to speed up dictionary lookups. Return the string itself or\n" -"the previously interned string object with the same value."); - -#define SYS_INTERN_METHODDEF \ - {"intern", (PyCFunction)sys_intern, METH_O, sys_intern__doc__}, - -static PyObject * -sys_intern_impl(PyObject *module, PyObject *s); - -static PyObject * -sys_intern(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - PyObject *s; - - if (!PyUnicode_Check(arg)) { - _PyArg_BadArgument("intern", "argument", "str", arg); - goto exit; - } - if (PyUnicode_READY(arg) == -1) { - goto exit; - } - s = arg; - return_value = sys_intern_impl(module, s); - -exit: - return return_value; -} - -PyDoc_STRVAR(sys_gettrace__doc__, -"gettrace($module, /)\n" -"--\n" -"\n" -"Return the global debug tracing function set with sys.settrace.\n" -"\n" -"See the debugger chapter in the library manual."); - -#define SYS_GETTRACE_METHODDEF \ - {"gettrace", (PyCFunction)sys_gettrace, METH_NOARGS, sys_gettrace__doc__}, - -static PyObject * -sys_gettrace_impl(PyObject *module); - -static PyObject * -sys_gettrace(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return sys_gettrace_impl(module); -} - -PyDoc_STRVAR(sys_getprofile__doc__, -"getprofile($module, /)\n" -"--\n" -"\n" -"Return the profiling function set with sys.setprofile.\n" -"\n" -"See the profiler chapter in the library manual."); - -#define SYS_GETPROFILE_METHODDEF \ - {"getprofile", (PyCFunction)sys_getprofile, METH_NOARGS, sys_getprofile__doc__}, - -static PyObject * -sys_getprofile_impl(PyObject *module); - -static PyObject * -sys_getprofile(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return sys_getprofile_impl(module); -} - -PyDoc_STRVAR(sys_setswitchinterval__doc__, -"setswitchinterval($module, interval, /)\n" -"--\n" -"\n" -"Set the ideal thread switching delay inside the Python interpreter.\n" -"\n" -"The actual frequency of switching threads can be lower if the\n" -"interpreter executes long sequences of uninterruptible code\n" -"(this is implementation-specific and workload-dependent).\n" -"\n" -"The parameter must represent the desired switching delay in seconds\n" -"A typical value is 0.005 (5 milliseconds)."); - -#define SYS_SETSWITCHINTERVAL_METHODDEF \ - {"setswitchinterval", (PyCFunction)sys_setswitchinterval, METH_O, sys_setswitchinterval__doc__}, - -static PyObject * -sys_setswitchinterval_impl(PyObject *module, double interval); - -static PyObject * -sys_setswitchinterval(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - double interval; - - if (PyFloat_CheckExact(arg)) { - interval = PyFloat_AS_DOUBLE(arg); - } - else - { - interval = PyFloat_AsDouble(arg); - if (interval == -1.0 && PyErr_Occurred()) { - goto exit; - } - } - return_value = sys_setswitchinterval_impl(module, interval); - -exit: - return return_value; -} - -PyDoc_STRVAR(sys_getswitchinterval__doc__, -"getswitchinterval($module, /)\n" -"--\n" -"\n" -"Return the current thread switch interval; see sys.setswitchinterval()."); - -#define SYS_GETSWITCHINTERVAL_METHODDEF \ - {"getswitchinterval", (PyCFunction)sys_getswitchinterval, METH_NOARGS, sys_getswitchinterval__doc__}, - -static double -sys_getswitchinterval_impl(PyObject *module); - -static PyObject * -sys_getswitchinterval(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - PyObject *return_value = NULL; - double _return_value; - - _return_value = sys_getswitchinterval_impl(module); - if ((_return_value == -1.0) && PyErr_Occurred()) { - goto exit; - } - return_value = PyFloat_FromDouble(_return_value); - -exit: - return return_value; -} - -PyDoc_STRVAR(sys_setrecursionlimit__doc__, -"setrecursionlimit($module, limit, /)\n" -"--\n" -"\n" -"Set the maximum depth of the Python interpreter stack to n.\n" -"\n" -"This limit prevents infinite recursion from causing an overflow of the C\n" -"stack and crashing Python. The highest possible limit is platform-\n" -"dependent."); - -#define SYS_SETRECURSIONLIMIT_METHODDEF \ - {"setrecursionlimit", (PyCFunction)sys_setrecursionlimit, METH_O, sys_setrecursionlimit__doc__}, - -static PyObject * -sys_setrecursionlimit_impl(PyObject *module, int new_limit); - -static PyObject * -sys_setrecursionlimit(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - int new_limit; - - new_limit = _PyLong_AsInt(arg); - if (new_limit == -1 && PyErr_Occurred()) { - goto exit; - } - return_value = sys_setrecursionlimit_impl(module, new_limit); - -exit: - return return_value; -} - -PyDoc_STRVAR(sys_set_coroutine_origin_tracking_depth__doc__, -"set_coroutine_origin_tracking_depth($module, /, depth)\n" -"--\n" -"\n" -"Enable or disable origin tracking for coroutine objects in this thread.\n" -"\n" -"Coroutine objects will track \'depth\' frames of traceback information\n" -"about where they came from, available in their cr_origin attribute.\n" -"\n" -"Set a depth of 0 to disable."); - -#define SYS_SET_COROUTINE_ORIGIN_TRACKING_DEPTH_METHODDEF \ - {"set_coroutine_origin_tracking_depth", (PyCFunction)(void(*)(void))sys_set_coroutine_origin_tracking_depth, METH_FASTCALL|METH_KEYWORDS, sys_set_coroutine_origin_tracking_depth__doc__}, - -static PyObject * -sys_set_coroutine_origin_tracking_depth_impl(PyObject *module, int depth); - -static PyObject * -sys_set_coroutine_origin_tracking_depth(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"depth", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "set_coroutine_origin_tracking_depth", 0}; - PyObject *argsbuf[1]; - int depth; - - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); - if (!args) { - goto exit; - } - depth = _PyLong_AsInt(args[0]); - if (depth == -1 && PyErr_Occurred()) { - goto exit; - } - return_value = sys_set_coroutine_origin_tracking_depth_impl(module, depth); - -exit: - return return_value; -} - -PyDoc_STRVAR(sys_get_coroutine_origin_tracking_depth__doc__, -"get_coroutine_origin_tracking_depth($module, /)\n" -"--\n" -"\n" -"Check status of origin tracking for coroutine objects in this thread."); - -#define SYS_GET_COROUTINE_ORIGIN_TRACKING_DEPTH_METHODDEF \ - {"get_coroutine_origin_tracking_depth", (PyCFunction)sys_get_coroutine_origin_tracking_depth, METH_NOARGS, sys_get_coroutine_origin_tracking_depth__doc__}, - -static int -sys_get_coroutine_origin_tracking_depth_impl(PyObject *module); - -static PyObject * -sys_get_coroutine_origin_tracking_depth(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - PyObject *return_value = NULL; - int _return_value; - - _return_value = sys_get_coroutine_origin_tracking_depth_impl(module); - if ((_return_value == -1) && PyErr_Occurred()) { - goto exit; - } - return_value = PyLong_FromLong((long)_return_value); - -exit: - return return_value; -} - -PyDoc_STRVAR(sys_get_asyncgen_hooks__doc__, -"get_asyncgen_hooks($module, /)\n" -"--\n" -"\n" -"Return the installed asynchronous generators hooks.\n" -"\n" -"This returns a namedtuple of the form (firstiter, finalizer)."); - -#define SYS_GET_ASYNCGEN_HOOKS_METHODDEF \ - {"get_asyncgen_hooks", (PyCFunction)sys_get_asyncgen_hooks, METH_NOARGS, sys_get_asyncgen_hooks__doc__}, - -static PyObject * -sys_get_asyncgen_hooks_impl(PyObject *module); - -static PyObject * -sys_get_asyncgen_hooks(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return sys_get_asyncgen_hooks_impl(module); -} - -PyDoc_STRVAR(sys_getrecursionlimit__doc__, -"getrecursionlimit($module, /)\n" -"--\n" -"\n" -"Return the current value of the recursion limit.\n" -"\n" -"The recursion limit is the maximum depth of the Python interpreter\n" -"stack. This limit prevents infinite recursion from causing an overflow\n" -"of the C stack and crashing Python."); - -#define SYS_GETRECURSIONLIMIT_METHODDEF \ - {"getrecursionlimit", (PyCFunction)sys_getrecursionlimit, METH_NOARGS, sys_getrecursionlimit__doc__}, - -static PyObject * -sys_getrecursionlimit_impl(PyObject *module); - -static PyObject * -sys_getrecursionlimit(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return sys_getrecursionlimit_impl(module); -} - -#if defined(MS_WINDOWS) - -PyDoc_STRVAR(sys_getwindowsversion__doc__, -"getwindowsversion($module, /)\n" -"--\n" -"\n" -"Return info about the running version of Windows as a named tuple.\n" -"\n" -"The members are named: major, minor, build, platform, service_pack,\n" -"service_pack_major, service_pack_minor, suite_mask, product_type and\n" -"platform_version. For backward compatibility, only the first 5 items\n" -"are available by indexing. All elements are numbers, except\n" -"service_pack and platform_type which are strings, and platform_version\n" -"which is a 3-tuple. Platform is always 2. Product_type may be 1 for a\n" -"workstation, 2 for a domain controller, 3 for a server.\n" -"Platform_version is a 3-tuple containing a version number that is\n" -"intended for identifying the OS rather than feature detection."); - -#define SYS_GETWINDOWSVERSION_METHODDEF \ - {"getwindowsversion", (PyCFunction)sys_getwindowsversion, METH_NOARGS, sys_getwindowsversion__doc__}, - -static PyObject * -sys_getwindowsversion_impl(PyObject *module); - -static PyObject * -sys_getwindowsversion(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return sys_getwindowsversion_impl(module); -} - -#endif /* defined(MS_WINDOWS) */ - -#if defined(MS_WINDOWS) - -PyDoc_STRVAR(sys__enablelegacywindowsfsencoding__doc__, -"_enablelegacywindowsfsencoding($module, /)\n" -"--\n" -"\n" -"Changes the default filesystem encoding to mbcs:replace.\n" -"\n" -"This is done for consistency with earlier versions of Python. See PEP\n" -"529 for more information.\n" -"\n" -"This is equivalent to defining the PYTHONLEGACYWINDOWSFSENCODING\n" -"environment variable before launching Python."); - -#define SYS__ENABLELEGACYWINDOWSFSENCODING_METHODDEF \ - {"_enablelegacywindowsfsencoding", (PyCFunction)sys__enablelegacywindowsfsencoding, METH_NOARGS, sys__enablelegacywindowsfsencoding__doc__}, - -static PyObject * -sys__enablelegacywindowsfsencoding_impl(PyObject *module); - -static PyObject * -sys__enablelegacywindowsfsencoding(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return sys__enablelegacywindowsfsencoding_impl(module); -} - -#endif /* defined(MS_WINDOWS) */ - -#if defined(HAVE_DLOPEN) - -PyDoc_STRVAR(sys_setdlopenflags__doc__, -"setdlopenflags($module, flags, /)\n" -"--\n" -"\n" -"Set the flags used by the interpreter for dlopen calls.\n" -"\n" -"This is used, for example, when the interpreter loads extension\n" -"modules. Among other things, this will enable a lazy resolving of\n" -"symbols when importing a module, if called as sys.setdlopenflags(0).\n" -"To share symbols across extension modules, call as\n" -"sys.setdlopenflags(os.RTLD_GLOBAL). Symbolic names for the flag\n" -"modules can be found in the os module (RTLD_xxx constants, e.g.\n" -"os.RTLD_LAZY)."); - -#define SYS_SETDLOPENFLAGS_METHODDEF \ - {"setdlopenflags", (PyCFunction)sys_setdlopenflags, METH_O, sys_setdlopenflags__doc__}, - -static PyObject * -sys_setdlopenflags_impl(PyObject *module, int new_val); - -static PyObject * -sys_setdlopenflags(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - int new_val; - - new_val = _PyLong_AsInt(arg); - if (new_val == -1 && PyErr_Occurred()) { - goto exit; - } - return_value = sys_setdlopenflags_impl(module, new_val); - -exit: - return return_value; -} - -#endif /* defined(HAVE_DLOPEN) */ - -#if defined(HAVE_DLOPEN) - -PyDoc_STRVAR(sys_getdlopenflags__doc__, -"getdlopenflags($module, /)\n" -"--\n" -"\n" -"Return the current value of the flags that are used for dlopen calls.\n" -"\n" -"The flag constants are defined in the os module."); - -#define SYS_GETDLOPENFLAGS_METHODDEF \ - {"getdlopenflags", (PyCFunction)sys_getdlopenflags, METH_NOARGS, sys_getdlopenflags__doc__}, - -static PyObject * -sys_getdlopenflags_impl(PyObject *module); - -static PyObject * -sys_getdlopenflags(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return sys_getdlopenflags_impl(module); -} - -#endif /* defined(HAVE_DLOPEN) */ - -#if defined(USE_MALLOPT) - -PyDoc_STRVAR(sys_mdebug__doc__, -"mdebug($module, flag, /)\n" -"--\n" -"\n"); - -#define SYS_MDEBUG_METHODDEF \ - {"mdebug", (PyCFunction)sys_mdebug, METH_O, sys_mdebug__doc__}, - -static PyObject * -sys_mdebug_impl(PyObject *module, int flag); - -static PyObject * -sys_mdebug(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - int flag; - - flag = _PyLong_AsInt(arg); - if (flag == -1 && PyErr_Occurred()) { - goto exit; - } - return_value = sys_mdebug_impl(module, flag); - -exit: - return return_value; -} - -#endif /* defined(USE_MALLOPT) */ - -PyDoc_STRVAR(sys_getrefcount__doc__, -"getrefcount($module, object, /)\n" -"--\n" -"\n" -"Return the reference count of object.\n" -"\n" -"The count returned is generally one higher than you might expect,\n" -"because it includes the (temporary) reference as an argument to\n" -"getrefcount()."); - -#define SYS_GETREFCOUNT_METHODDEF \ - {"getrefcount", (PyCFunction)sys_getrefcount, METH_O, sys_getrefcount__doc__}, - -static Py_ssize_t -sys_getrefcount_impl(PyObject *module, PyObject *object); - -static PyObject * -sys_getrefcount(PyObject *module, PyObject *object) -{ - PyObject *return_value = NULL; - Py_ssize_t _return_value; - - _return_value = sys_getrefcount_impl(module, object); - if ((_return_value == -1) && PyErr_Occurred()) { - goto exit; - } - return_value = PyLong_FromSsize_t(_return_value); - -exit: - return return_value; -} - -#if defined(Py_REF_DEBUG) - -PyDoc_STRVAR(sys_gettotalrefcount__doc__, -"gettotalrefcount($module, /)\n" -"--\n" -"\n"); - -#define SYS_GETTOTALREFCOUNT_METHODDEF \ - {"gettotalrefcount", (PyCFunction)sys_gettotalrefcount, METH_NOARGS, sys_gettotalrefcount__doc__}, - -static Py_ssize_t -sys_gettotalrefcount_impl(PyObject *module); - -static PyObject * -sys_gettotalrefcount(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - PyObject *return_value = NULL; - Py_ssize_t _return_value; - - _return_value = sys_gettotalrefcount_impl(module); - if ((_return_value == -1) && PyErr_Occurred()) { - goto exit; - } - return_value = PyLong_FromSsize_t(_return_value); - -exit: - return return_value; -} - -#endif /* defined(Py_REF_DEBUG) */ - -PyDoc_STRVAR(sys_getallocatedblocks__doc__, -"getallocatedblocks($module, /)\n" -"--\n" -"\n" -"Return the number of memory blocks currently allocated."); - -#define SYS_GETALLOCATEDBLOCKS_METHODDEF \ - {"getallocatedblocks", (PyCFunction)sys_getallocatedblocks, METH_NOARGS, sys_getallocatedblocks__doc__}, - -static Py_ssize_t -sys_getallocatedblocks_impl(PyObject *module); - -static PyObject * -sys_getallocatedblocks(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - PyObject *return_value = NULL; - Py_ssize_t _return_value; - - _return_value = sys_getallocatedblocks_impl(module); - if ((_return_value == -1) && PyErr_Occurred()) { - goto exit; - } - return_value = PyLong_FromSsize_t(_return_value); - -exit: - return return_value; -} - -PyDoc_STRVAR(sys__getframe__doc__, -"_getframe($module, depth=0, /)\n" -"--\n" -"\n" -"Return a frame object from the call stack.\n" -"\n" -"If optional integer depth is given, return the frame object that many\n" -"calls below the top of the stack. If that is deeper than the call\n" -"stack, ValueError is raised. The default for depth is zero, returning\n" -"the frame at the top of the call stack.\n" -"\n" -"This function should be used for internal and specialized purposes\n" -"only."); - -#define SYS__GETFRAME_METHODDEF \ - {"_getframe", (PyCFunction)(void(*)(void))sys__getframe, METH_FASTCALL, sys__getframe__doc__}, - -static PyObject * -sys__getframe_impl(PyObject *module, int depth); - -static PyObject * -sys__getframe(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - int depth = 0; - - if (!_PyArg_CheckPositional("_getframe", nargs, 0, 1)) { - goto exit; - } - if (nargs < 1) { - goto skip_optional; - } - depth = _PyLong_AsInt(args[0]); - if (depth == -1 && PyErr_Occurred()) { - goto exit; - } -skip_optional: - return_value = sys__getframe_impl(module, depth); - -exit: - return return_value; -} - -PyDoc_STRVAR(sys__current_frames__doc__, -"_current_frames($module, /)\n" -"--\n" -"\n" -"Return a dict mapping each thread\'s thread id to its current stack frame.\n" -"\n" -"This function should be used for specialized purposes only."); - -#define SYS__CURRENT_FRAMES_METHODDEF \ - {"_current_frames", (PyCFunction)sys__current_frames, METH_NOARGS, sys__current_frames__doc__}, - -static PyObject * -sys__current_frames_impl(PyObject *module); - -static PyObject * -sys__current_frames(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return sys__current_frames_impl(module); -} - -PyDoc_STRVAR(sys__current_exceptions__doc__, -"_current_exceptions($module, /)\n" -"--\n" -"\n" -"Return a dict mapping each thread\'s identifier to its current raised exception.\n" -"\n" -"This function should be used for specialized purposes only."); - -#define SYS__CURRENT_EXCEPTIONS_METHODDEF \ - {"_current_exceptions", (PyCFunction)sys__current_exceptions, METH_NOARGS, sys__current_exceptions__doc__}, - -static PyObject * -sys__current_exceptions_impl(PyObject *module); - -static PyObject * -sys__current_exceptions(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return sys__current_exceptions_impl(module); -} - -PyDoc_STRVAR(sys_call_tracing__doc__, -"call_tracing($module, func, args, /)\n" -"--\n" -"\n" -"Call func(*args), while tracing is enabled.\n" -"\n" -"The tracing state is saved, and restored afterwards. This is intended\n" -"to be called from a debugger from a checkpoint, to recursively debug\n" -"some other code."); - -#define SYS_CALL_TRACING_METHODDEF \ - {"call_tracing", (PyCFunction)(void(*)(void))sys_call_tracing, METH_FASTCALL, sys_call_tracing__doc__}, - -static PyObject * -sys_call_tracing_impl(PyObject *module, PyObject *func, PyObject *funcargs); - -static PyObject * -sys_call_tracing(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *func; - PyObject *funcargs; - - if (!_PyArg_CheckPositional("call_tracing", nargs, 2, 2)) { - goto exit; - } - func = args[0]; - if (!PyTuple_Check(args[1])) { - _PyArg_BadArgument("call_tracing", "argument 2", "tuple", args[1]); - goto exit; - } - funcargs = args[1]; - return_value = sys_call_tracing_impl(module, func, funcargs); - -exit: - return return_value; -} - -PyDoc_STRVAR(sys__debugmallocstats__doc__, -"_debugmallocstats($module, /)\n" -"--\n" -"\n" -"Print summary info to stderr about the state of pymalloc\'s structures.\n" -"\n" -"In Py_DEBUG mode, also perform some expensive internal consistency\n" -"checks."); - -#define SYS__DEBUGMALLOCSTATS_METHODDEF \ - {"_debugmallocstats", (PyCFunction)sys__debugmallocstats, METH_NOARGS, sys__debugmallocstats__doc__}, - -static PyObject * -sys__debugmallocstats_impl(PyObject *module); - -static PyObject * -sys__debugmallocstats(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return sys__debugmallocstats_impl(module); -} - -PyDoc_STRVAR(sys__clear_type_cache__doc__, -"_clear_type_cache($module, /)\n" -"--\n" -"\n" -"Clear the internal type lookup cache."); - -#define SYS__CLEAR_TYPE_CACHE_METHODDEF \ - {"_clear_type_cache", (PyCFunction)sys__clear_type_cache, METH_NOARGS, sys__clear_type_cache__doc__}, - -static PyObject * -sys__clear_type_cache_impl(PyObject *module); - -static PyObject * -sys__clear_type_cache(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return sys__clear_type_cache_impl(module); -} - -PyDoc_STRVAR(sys_is_finalizing__doc__, -"is_finalizing($module, /)\n" -"--\n" -"\n" -"Return True if Python is exiting."); - -#define SYS_IS_FINALIZING_METHODDEF \ - {"is_finalizing", (PyCFunction)sys_is_finalizing, METH_NOARGS, sys_is_finalizing__doc__}, - -static PyObject * -sys_is_finalizing_impl(PyObject *module); - -static PyObject * -sys_is_finalizing(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return sys_is_finalizing_impl(module); -} - -#if defined(ANDROID_API_LEVEL) - -PyDoc_STRVAR(sys_getandroidapilevel__doc__, -"getandroidapilevel($module, /)\n" -"--\n" -"\n" -"Return the build time API version of Android as an integer."); - -#define SYS_GETANDROIDAPILEVEL_METHODDEF \ - {"getandroidapilevel", (PyCFunction)sys_getandroidapilevel, METH_NOARGS, sys_getandroidapilevel__doc__}, - -static PyObject * -sys_getandroidapilevel_impl(PyObject *module); - -static PyObject * -sys_getandroidapilevel(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return sys_getandroidapilevel_impl(module); -} - -#endif /* defined(ANDROID_API_LEVEL) */ - -PyDoc_STRVAR(sys__deactivate_opcache__doc__, -"_deactivate_opcache($module, /)\n" -"--\n" -"\n" -"Deactivate the opcode cache permanently"); - -#define SYS__DEACTIVATE_OPCACHE_METHODDEF \ - {"_deactivate_opcache", (PyCFunction)sys__deactivate_opcache, METH_NOARGS, sys__deactivate_opcache__doc__}, - -static PyObject * -sys__deactivate_opcache_impl(PyObject *module); - -static PyObject * -sys__deactivate_opcache(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return sys__deactivate_opcache_impl(module); -} - -#ifndef SYS_GETWINDOWSVERSION_METHODDEF - #define SYS_GETWINDOWSVERSION_METHODDEF -#endif /* !defined(SYS_GETWINDOWSVERSION_METHODDEF) */ - -#ifndef SYS__ENABLELEGACYWINDOWSFSENCODING_METHODDEF - #define SYS__ENABLELEGACYWINDOWSFSENCODING_METHODDEF -#endif /* !defined(SYS__ENABLELEGACYWINDOWSFSENCODING_METHODDEF) */ - -#ifndef SYS_SETDLOPENFLAGS_METHODDEF - #define SYS_SETDLOPENFLAGS_METHODDEF -#endif /* !defined(SYS_SETDLOPENFLAGS_METHODDEF) */ - -#ifndef SYS_GETDLOPENFLAGS_METHODDEF - #define SYS_GETDLOPENFLAGS_METHODDEF -#endif /* !defined(SYS_GETDLOPENFLAGS_METHODDEF) */ - -#ifndef SYS_MDEBUG_METHODDEF - #define SYS_MDEBUG_METHODDEF -#endif /* !defined(SYS_MDEBUG_METHODDEF) */ - -#ifndef SYS_GETTOTALREFCOUNT_METHODDEF - #define SYS_GETTOTALREFCOUNT_METHODDEF -#endif /* !defined(SYS_GETTOTALREFCOUNT_METHODDEF) */ - -#ifndef SYS_GETANDROIDAPILEVEL_METHODDEF - #define SYS_GETANDROIDAPILEVEL_METHODDEF -#endif /* !defined(SYS_GETANDROIDAPILEVEL_METHODDEF) */ -/*[clinic end generated code: output=68c62b9ca317a0c8 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Python/clinic/traceback.c.h b/contrib/tools/python3/src/Python/clinic/traceback.c.h deleted file mode 100644 index 404a0c416d3..00000000000 --- a/contrib/tools/python3/src/Python/clinic/traceback.c.h +++ /dev/null @@ -1,52 +0,0 @@ -/*[clinic input] -preserve -[clinic start generated code]*/ - -PyDoc_STRVAR(tb_new__doc__, -"TracebackType(tb_next, tb_frame, tb_lasti, tb_lineno)\n" -"--\n" -"\n" -"Create a new traceback object."); - -static PyObject * -tb_new_impl(PyTypeObject *type, PyObject *tb_next, PyFrameObject *tb_frame, - int tb_lasti, int tb_lineno); - -static PyObject * -tb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"tb_next", "tb_frame", "tb_lasti", "tb_lineno", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "TracebackType", 0}; - PyObject *argsbuf[4]; - PyObject * const *fastargs; - Py_ssize_t nargs = PyTuple_GET_SIZE(args); - PyObject *tb_next; - PyFrameObject *tb_frame; - int tb_lasti; - int tb_lineno; - - fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 4, 4, 0, argsbuf); - if (!fastargs) { - goto exit; - } - tb_next = fastargs[0]; - if (!PyObject_TypeCheck(fastargs[1], &PyFrame_Type)) { - _PyArg_BadArgument("TracebackType", "argument 'tb_frame'", (&PyFrame_Type)->tp_name, fastargs[1]); - goto exit; - } - tb_frame = (PyFrameObject *)fastargs[1]; - tb_lasti = _PyLong_AsInt(fastargs[2]); - if (tb_lasti == -1 && PyErr_Occurred()) { - goto exit; - } - tb_lineno = _PyLong_AsInt(fastargs[3]); - if (tb_lineno == -1 && PyErr_Occurred()) { - goto exit; - } - return_value = tb_new_impl(type, tb_next, tb_frame, tb_lasti, tb_lineno); - -exit: - return return_value; -} -/*[clinic end generated code: output=403778d7af5ebef9 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Python/codecs.c b/contrib/tools/python3/src/Python/codecs.c deleted file mode 100644 index fa329ce2436..00000000000 --- a/contrib/tools/python3/src/Python/codecs.c +++ /dev/null @@ -1,1536 +0,0 @@ -/* ------------------------------------------------------------------------ - - Python Codec Registry and support functions - -Written by Marc-Andre Lemburg ([email protected]). - -Copyright (c) Corporation for National Research Initiatives. - - ------------------------------------------------------------------------ */ - -#include "Python.h" -#include "pycore_interp.h" // PyInterpreterState.codec_search_path -#include "pycore_pystate.h" // _PyInterpreterState_GET() -#include "pycore_ucnhash.h" // _PyUnicode_Name_CAPI -#include <ctype.h> - -const char *Py_hexdigits = "0123456789abcdef"; - -/* --- Codec Registry ----------------------------------------------------- */ - -/* Import the standard encodings package which will register the first - codec search function. - - This is done in a lazy way so that the Unicode implementation does - not downgrade startup time of scripts not needing it. - - ImportErrors are silently ignored by this function. Only one try is - made. - -*/ - -static int _PyCodecRegistry_Init(void); /* Forward */ - -int PyCodec_Register(PyObject *search_function) -{ - PyInterpreterState *interp = _PyInterpreterState_GET(); - if (interp->codec_search_path == NULL && _PyCodecRegistry_Init()) - goto onError; - if (search_function == NULL) { - PyErr_BadArgument(); - goto onError; - } - if (!PyCallable_Check(search_function)) { - PyErr_SetString(PyExc_TypeError, "argument must be callable"); - goto onError; - } - return PyList_Append(interp->codec_search_path, search_function); - - onError: - return -1; -} - -int -PyCodec_Unregister(PyObject *search_function) -{ - PyInterpreterState *interp = PyInterpreterState_Get(); - PyObject *codec_search_path = interp->codec_search_path; - /* Do nothing if codec_search_path is not created yet or was cleared. */ - if (codec_search_path == NULL) { - return 0; - } - - assert(PyList_CheckExact(codec_search_path)); - Py_ssize_t n = PyList_GET_SIZE(codec_search_path); - for (Py_ssize_t i = 0; i < n; i++) { - PyObject *item = PyList_GET_ITEM(codec_search_path, i); - if (item == search_function) { - if (interp->codec_search_cache != NULL) { - assert(PyDict_CheckExact(interp->codec_search_cache)); - PyDict_Clear(interp->codec_search_cache); - } - return PyList_SetSlice(codec_search_path, i, i+1, NULL); - } - } - return 0; -} - -extern int _Py_normalize_encoding(const char *, char *, size_t); - -/* Convert a string to a normalized Python string(decoded from UTF-8): all characters are - converted to lower case, spaces and hyphens are replaced with underscores. */ - -static -PyObject *normalizestring(const char *string) -{ - size_t len = strlen(string); - char *encoding; - PyObject *v; - - if (len > PY_SSIZE_T_MAX) { - PyErr_SetString(PyExc_OverflowError, "string is too large"); - return NULL; - } - - encoding = PyMem_Malloc(len + 1); - if (encoding == NULL) - return PyErr_NoMemory(); - - if (!_Py_normalize_encoding(string, encoding, len + 1)) - { - PyErr_SetString(PyExc_RuntimeError, "_Py_normalize_encoding() failed"); - PyMem_Free(encoding); - return NULL; - } - - v = PyUnicode_FromString(encoding); - PyMem_Free(encoding); - return v; -} - -/* Lookup the given encoding and return a tuple providing the codec - facilities. - - The encoding string is looked up converted to all lower-case - characters. This makes encodings looked up through this mechanism - effectively case-insensitive. - - If no codec is found, a LookupError is set and NULL returned. - - As side effect, this tries to load the encodings package, if not - yet done. This is part of the lazy load strategy for the encodings - package. - -*/ - -PyObject *_PyCodec_Lookup(const char *encoding) -{ - if (encoding == NULL) { - PyErr_BadArgument(); - return NULL; - } - - PyInterpreterState *interp = _PyInterpreterState_GET(); - if (interp->codec_search_path == NULL && _PyCodecRegistry_Init()) { - return NULL; - } - - /* Convert the encoding to a normalized Python string: all - characters are converted to lower case, spaces and hyphens are - replaced with underscores. */ - PyObject *v = normalizestring(encoding); - if (v == NULL) { - return NULL; - } - PyUnicode_InternInPlace(&v); - - /* First, try to lookup the name in the registry dictionary */ - PyObject *result = PyDict_GetItemWithError(interp->codec_search_cache, v); - if (result != NULL) { - Py_INCREF(result); - Py_DECREF(v); - return result; - } - else if (PyErr_Occurred()) { - goto onError; - } - - /* Next, scan the search functions in order of registration */ - const Py_ssize_t len = PyList_Size(interp->codec_search_path); - if (len < 0) - goto onError; - if (len == 0) { - PyErr_SetString(PyExc_LookupError, - "no codec search functions registered: " - "can't find encoding"); - goto onError; - } - - Py_ssize_t i; - for (i = 0; i < len; i++) { - PyObject *func; - - func = PyList_GetItem(interp->codec_search_path, i); - if (func == NULL) - goto onError; - result = PyObject_CallOneArg(func, v); - if (result == NULL) - goto onError; - if (result == Py_None) { - Py_DECREF(result); - continue; - } - if (!PyTuple_Check(result) || PyTuple_GET_SIZE(result) != 4) { - PyErr_SetString(PyExc_TypeError, - "codec search functions must return 4-tuples"); - Py_DECREF(result); - goto onError; - } - break; - } - if (i == len) { - /* XXX Perhaps we should cache misses too ? */ - PyErr_Format(PyExc_LookupError, - "unknown encoding: %s", encoding); - goto onError; - } - - /* Cache and return the result */ - if (PyDict_SetItem(interp->codec_search_cache, v, result) < 0) { - Py_DECREF(result); - goto onError; - } - Py_DECREF(v); - return result; - - onError: - Py_DECREF(v); - return NULL; -} - -/* Codec registry encoding check API. */ - -int PyCodec_KnownEncoding(const char *encoding) -{ - PyObject *codecs; - - codecs = _PyCodec_Lookup(encoding); - if (!codecs) { - PyErr_Clear(); - return 0; - } - else { - Py_DECREF(codecs); - return 1; - } -} - -static -PyObject *args_tuple(PyObject *object, - const char *errors) -{ - PyObject *args; - - args = PyTuple_New(1 + (errors != NULL)); - if (args == NULL) - return NULL; - Py_INCREF(object); - PyTuple_SET_ITEM(args,0,object); - if (errors) { - PyObject *v; - - v = PyUnicode_FromString(errors); - if (v == NULL) { - Py_DECREF(args); - return NULL; - } - PyTuple_SET_ITEM(args, 1, v); - } - return args; -} - -/* Helper function to get a codec item */ - -static -PyObject *codec_getitem(const char *encoding, int index) -{ - PyObject *codecs; - PyObject *v; - - codecs = _PyCodec_Lookup(encoding); - if (codecs == NULL) - return NULL; - v = PyTuple_GET_ITEM(codecs, index); - Py_DECREF(codecs); - Py_INCREF(v); - return v; -} - -/* Helper functions to create an incremental codec. */ -static -PyObject *codec_makeincrementalcodec(PyObject *codec_info, - const char *errors, - const char *attrname) -{ - PyObject *ret, *inccodec; - - inccodec = PyObject_GetAttrString(codec_info, attrname); - if (inccodec == NULL) - return NULL; - if (errors) - ret = PyObject_CallFunction(inccodec, "s", errors); - else - ret = _PyObject_CallNoArg(inccodec); - Py_DECREF(inccodec); - return ret; -} - -static -PyObject *codec_getincrementalcodec(const char *encoding, - const char *errors, - const char *attrname) -{ - PyObject *codec_info, *ret; - - codec_info = _PyCodec_Lookup(encoding); - if (codec_info == NULL) - return NULL; - ret = codec_makeincrementalcodec(codec_info, errors, attrname); - Py_DECREF(codec_info); - return ret; -} - -/* Helper function to create a stream codec. */ - -static -PyObject *codec_getstreamcodec(const char *encoding, - PyObject *stream, - const char *errors, - const int index) -{ - PyObject *codecs, *streamcodec, *codeccls; - - codecs = _PyCodec_Lookup(encoding); - if (codecs == NULL) - return NULL; - - codeccls = PyTuple_GET_ITEM(codecs, index); - if (errors != NULL) - streamcodec = PyObject_CallFunction(codeccls, "Os", stream, errors); - else - streamcodec = PyObject_CallOneArg(codeccls, stream); - Py_DECREF(codecs); - return streamcodec; -} - -/* Helpers to work with the result of _PyCodec_Lookup - - */ -PyObject *_PyCodecInfo_GetIncrementalDecoder(PyObject *codec_info, - const char *errors) -{ - return codec_makeincrementalcodec(codec_info, errors, - "incrementaldecoder"); -} - -PyObject *_PyCodecInfo_GetIncrementalEncoder(PyObject *codec_info, - const char *errors) -{ - return codec_makeincrementalcodec(codec_info, errors, - "incrementalencoder"); -} - - -/* Convenience APIs to query the Codec registry. - - All APIs return a codec object with incremented refcount. - - */ - -PyObject *PyCodec_Encoder(const char *encoding) -{ - return codec_getitem(encoding, 0); -} - -PyObject *PyCodec_Decoder(const char *encoding) -{ - return codec_getitem(encoding, 1); -} - -PyObject *PyCodec_IncrementalEncoder(const char *encoding, - const char *errors) -{ - return codec_getincrementalcodec(encoding, errors, "incrementalencoder"); -} - -PyObject *PyCodec_IncrementalDecoder(const char *encoding, - const char *errors) -{ - return codec_getincrementalcodec(encoding, errors, "incrementaldecoder"); -} - -PyObject *PyCodec_StreamReader(const char *encoding, - PyObject *stream, - const char *errors) -{ - return codec_getstreamcodec(encoding, stream, errors, 2); -} - -PyObject *PyCodec_StreamWriter(const char *encoding, - PyObject *stream, - const char *errors) -{ - return codec_getstreamcodec(encoding, stream, errors, 3); -} - -/* Helper that tries to ensure the reported exception chain indicates the - * codec that was invoked to trigger the failure without changing the type - * of the exception raised. - */ -static void -wrap_codec_error(const char *operation, - const char *encoding) -{ - /* TrySetFromCause will replace the active exception with a suitably - * updated clone if it can, otherwise it will leave the original - * exception alone. - */ - _PyErr_TrySetFromCause("%s with '%s' codec failed", - operation, encoding); -} - -/* Encode an object (e.g. a Unicode object) using the given encoding - and return the resulting encoded object (usually a Python string). - - errors is passed to the encoder factory as argument if non-NULL. */ - -static PyObject * -_PyCodec_EncodeInternal(PyObject *object, - PyObject *encoder, - const char *encoding, - const char *errors) -{ - PyObject *args = NULL, *result = NULL; - PyObject *v = NULL; - - args = args_tuple(object, errors); - if (args == NULL) - goto onError; - - result = PyObject_Call(encoder, args, NULL); - if (result == NULL) { - wrap_codec_error("encoding", encoding); - goto onError; - } - - if (!PyTuple_Check(result) || - PyTuple_GET_SIZE(result) != 2) { - PyErr_SetString(PyExc_TypeError, - "encoder must return a tuple (object, integer)"); - goto onError; - } - v = PyTuple_GET_ITEM(result,0); - Py_INCREF(v); - /* We don't check or use the second (integer) entry. */ - - Py_DECREF(args); - Py_DECREF(encoder); - Py_DECREF(result); - return v; - - onError: - Py_XDECREF(result); - Py_XDECREF(args); - Py_XDECREF(encoder); - return NULL; -} - -/* Decode an object (usually a Python string) using the given encoding - and return an equivalent object (e.g. a Unicode object). - - errors is passed to the decoder factory as argument if non-NULL. */ - -static PyObject * -_PyCodec_DecodeInternal(PyObject *object, - PyObject *decoder, - const char *encoding, - const char *errors) -{ - PyObject *args = NULL, *result = NULL; - PyObject *v; - - args = args_tuple(object, errors); - if (args == NULL) - goto onError; - - result = PyObject_Call(decoder, args, NULL); - if (result == NULL) { - wrap_codec_error("decoding", encoding); - goto onError; - } - if (!PyTuple_Check(result) || - PyTuple_GET_SIZE(result) != 2) { - PyErr_SetString(PyExc_TypeError, - "decoder must return a tuple (object,integer)"); - goto onError; - } - v = PyTuple_GET_ITEM(result,0); - Py_INCREF(v); - /* We don't check or use the second (integer) entry. */ - - Py_DECREF(args); - Py_DECREF(decoder); - Py_DECREF(result); - return v; - - onError: - Py_XDECREF(args); - Py_XDECREF(decoder); - Py_XDECREF(result); - return NULL; -} - -/* Generic encoding/decoding API */ -PyObject *PyCodec_Encode(PyObject *object, - const char *encoding, - const char *errors) -{ - PyObject *encoder; - - encoder = PyCodec_Encoder(encoding); - if (encoder == NULL) - return NULL; - - return _PyCodec_EncodeInternal(object, encoder, encoding, errors); -} - -PyObject *PyCodec_Decode(PyObject *object, - const char *encoding, - const char *errors) -{ - PyObject *decoder; - - decoder = PyCodec_Decoder(encoding); - if (decoder == NULL) - return NULL; - - return _PyCodec_DecodeInternal(object, decoder, encoding, errors); -} - -/* Text encoding/decoding API */ -PyObject * _PyCodec_LookupTextEncoding(const char *encoding, - const char *alternate_command) -{ - _Py_IDENTIFIER(_is_text_encoding); - PyObject *codec; - PyObject *attr; - int is_text_codec; - - codec = _PyCodec_Lookup(encoding); - if (codec == NULL) - return NULL; - - /* Backwards compatibility: assume any raw tuple describes a text - * encoding, and the same for anything lacking the private - * attribute. - */ - if (!PyTuple_CheckExact(codec)) { - if (_PyObject_LookupAttrId(codec, &PyId__is_text_encoding, &attr) < 0) { - Py_DECREF(codec); - return NULL; - } - if (attr != NULL) { - is_text_codec = PyObject_IsTrue(attr); - Py_DECREF(attr); - if (is_text_codec <= 0) { - Py_DECREF(codec); - if (!is_text_codec) - PyErr_Format(PyExc_LookupError, - "'%.400s' is not a text encoding; " - "use %s to handle arbitrary codecs", - encoding, alternate_command); - return NULL; - } - } - } - - /* This appears to be a valid text encoding */ - return codec; -} - - -static -PyObject *codec_getitem_checked(const char *encoding, - const char *alternate_command, - int index) -{ - PyObject *codec; - PyObject *v; - - codec = _PyCodec_LookupTextEncoding(encoding, alternate_command); - if (codec == NULL) - return NULL; - - v = PyTuple_GET_ITEM(codec, index); - Py_INCREF(v); - Py_DECREF(codec); - return v; -} - -static PyObject * _PyCodec_TextEncoder(const char *encoding) -{ - return codec_getitem_checked(encoding, "codecs.encode()", 0); -} - -static PyObject * _PyCodec_TextDecoder(const char *encoding) -{ - return codec_getitem_checked(encoding, "codecs.decode()", 1); -} - -PyObject *_PyCodec_EncodeText(PyObject *object, - const char *encoding, - const char *errors) -{ - PyObject *encoder; - - encoder = _PyCodec_TextEncoder(encoding); - if (encoder == NULL) - return NULL; - - return _PyCodec_EncodeInternal(object, encoder, encoding, errors); -} - -PyObject *_PyCodec_DecodeText(PyObject *object, - const char *encoding, - const char *errors) -{ - PyObject *decoder; - - decoder = _PyCodec_TextDecoder(encoding); - if (decoder == NULL) - return NULL; - - return _PyCodec_DecodeInternal(object, decoder, encoding, errors); -} - -/* Register the error handling callback function error under the name - name. This function will be called by the codec when it encounters - an unencodable characters/undecodable bytes and doesn't know the - callback name, when name is specified as the error parameter - in the call to the encode/decode function. - Return 0 on success, -1 on error */ -int PyCodec_RegisterError(const char *name, PyObject *error) -{ - PyInterpreterState *interp = _PyInterpreterState_GET(); - if (interp->codec_search_path == NULL && _PyCodecRegistry_Init()) - return -1; - if (!PyCallable_Check(error)) { - PyErr_SetString(PyExc_TypeError, "handler must be callable"); - return -1; - } - return PyDict_SetItemString(interp->codec_error_registry, - name, error); -} - -/* Lookup the error handling callback function registered under the - name error. As a special case NULL can be passed, in which case - the error handling callback for strict encoding will be returned. */ -PyObject *PyCodec_LookupError(const char *name) -{ - PyObject *handler = NULL; - - PyInterpreterState *interp = _PyInterpreterState_GET(); - if (interp->codec_search_path == NULL && _PyCodecRegistry_Init()) - return NULL; - - if (name==NULL) - name = "strict"; - handler = _PyDict_GetItemStringWithError(interp->codec_error_registry, name); - if (handler) { - Py_INCREF(handler); - } - else if (!PyErr_Occurred()) { - PyErr_Format(PyExc_LookupError, "unknown error handler name '%.400s'", name); - } - return handler; -} - -static void wrong_exception_type(PyObject *exc) -{ - PyErr_Format(PyExc_TypeError, - "don't know how to handle %.200s in error callback", - Py_TYPE(exc)->tp_name); -} - -PyObject *PyCodec_StrictErrors(PyObject *exc) -{ - if (PyExceptionInstance_Check(exc)) - PyErr_SetObject(PyExceptionInstance_Class(exc), exc); - else - PyErr_SetString(PyExc_TypeError, "codec must pass exception instance"); - return NULL; -} - - -PyObject *PyCodec_IgnoreErrors(PyObject *exc) -{ - Py_ssize_t end; - - if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeEncodeError)) { - if (PyUnicodeEncodeError_GetEnd(exc, &end)) - return NULL; - } - else if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeDecodeError)) { - if (PyUnicodeDecodeError_GetEnd(exc, &end)) - return NULL; - } - else if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeTranslateError)) { - if (PyUnicodeTranslateError_GetEnd(exc, &end)) - return NULL; - } - else { - wrong_exception_type(exc); - return NULL; - } - return Py_BuildValue("(Nn)", PyUnicode_New(0, 0), end); -} - - -PyObject *PyCodec_ReplaceErrors(PyObject *exc) -{ - Py_ssize_t start, end, i, len; - - if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeEncodeError)) { - PyObject *res; - Py_UCS1 *outp; - if (PyUnicodeEncodeError_GetStart(exc, &start)) - return NULL; - if (PyUnicodeEncodeError_GetEnd(exc, &end)) - return NULL; - len = end - start; - res = PyUnicode_New(len, '?'); - if (res == NULL) - return NULL; - assert(PyUnicode_KIND(res) == PyUnicode_1BYTE_KIND); - outp = PyUnicode_1BYTE_DATA(res); - for (i = 0; i < len; ++i) - outp[i] = '?'; - assert(_PyUnicode_CheckConsistency(res, 1)); - return Py_BuildValue("(Nn)", res, end); - } - else if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeDecodeError)) { - if (PyUnicodeDecodeError_GetEnd(exc, &end)) - return NULL; - return Py_BuildValue("(Cn)", - (int)Py_UNICODE_REPLACEMENT_CHARACTER, - end); - } - else if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeTranslateError)) { - PyObject *res; - Py_UCS2 *outp; - if (PyUnicodeTranslateError_GetStart(exc, &start)) - return NULL; - if (PyUnicodeTranslateError_GetEnd(exc, &end)) - return NULL; - len = end - start; - res = PyUnicode_New(len, Py_UNICODE_REPLACEMENT_CHARACTER); - if (res == NULL) - return NULL; - assert(PyUnicode_KIND(res) == PyUnicode_2BYTE_KIND); - outp = PyUnicode_2BYTE_DATA(res); - for (i = 0; i < len; i++) - outp[i] = Py_UNICODE_REPLACEMENT_CHARACTER; - assert(_PyUnicode_CheckConsistency(res, 1)); - return Py_BuildValue("(Nn)", res, end); - } - else { - wrong_exception_type(exc); - return NULL; - } -} - -PyObject *PyCodec_XMLCharRefReplaceErrors(PyObject *exc) -{ - if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeEncodeError)) { - PyObject *restuple; - PyObject *object; - Py_ssize_t i; - Py_ssize_t start; - Py_ssize_t end; - PyObject *res; - Py_UCS1 *outp; - Py_ssize_t ressize; - Py_UCS4 ch; - if (PyUnicodeEncodeError_GetStart(exc, &start)) - return NULL; - if (PyUnicodeEncodeError_GetEnd(exc, &end)) - return NULL; - if (!(object = PyUnicodeEncodeError_GetObject(exc))) - return NULL; - if (end - start > PY_SSIZE_T_MAX / (2+7+1)) - end = start + PY_SSIZE_T_MAX / (2+7+1); - for (i = start, ressize = 0; i < end; ++i) { - /* object is guaranteed to be "ready" */ - ch = PyUnicode_READ_CHAR(object, i); - if (ch<10) - ressize += 2+1+1; - else if (ch<100) - ressize += 2+2+1; - else if (ch<1000) - ressize += 2+3+1; - else if (ch<10000) - ressize += 2+4+1; - else if (ch<100000) - ressize += 2+5+1; - else if (ch<1000000) - ressize += 2+6+1; - else - ressize += 2+7+1; - } - /* allocate replacement */ - res = PyUnicode_New(ressize, 127); - if (res == NULL) { - Py_DECREF(object); - return NULL; - } - outp = PyUnicode_1BYTE_DATA(res); - /* generate replacement */ - for (i = start; i < end; ++i) { - int digits; - int base; - ch = PyUnicode_READ_CHAR(object, i); - *outp++ = '&'; - *outp++ = '#'; - if (ch<10) { - digits = 1; - base = 1; - } - else if (ch<100) { - digits = 2; - base = 10; - } - else if (ch<1000) { - digits = 3; - base = 100; - } - else if (ch<10000) { - digits = 4; - base = 1000; - } - else if (ch<100000) { - digits = 5; - base = 10000; - } - else if (ch<1000000) { - digits = 6; - base = 100000; - } - else { - digits = 7; - base = 1000000; - } - while (digits-->0) { - *outp++ = '0' + ch/base; - ch %= base; - base /= 10; - } - *outp++ = ';'; - } - assert(_PyUnicode_CheckConsistency(res, 1)); - restuple = Py_BuildValue("(Nn)", res, end); - Py_DECREF(object); - return restuple; - } - else { - wrong_exception_type(exc); - return NULL; - } -} - -PyObject *PyCodec_BackslashReplaceErrors(PyObject *exc) -{ - PyObject *object; - Py_ssize_t i; - Py_ssize_t start; - Py_ssize_t end; - PyObject *res; - Py_UCS1 *outp; - int ressize; - Py_UCS4 c; - - if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeDecodeError)) { - const unsigned char *p; - if (PyUnicodeDecodeError_GetStart(exc, &start)) - return NULL; - if (PyUnicodeDecodeError_GetEnd(exc, &end)) - return NULL; - if (!(object = PyUnicodeDecodeError_GetObject(exc))) - return NULL; - p = (const unsigned char*)PyBytes_AS_STRING(object); - res = PyUnicode_New(4 * (end - start), 127); - if (res == NULL) { - Py_DECREF(object); - return NULL; - } - outp = PyUnicode_1BYTE_DATA(res); - for (i = start; i < end; i++, outp += 4) { - unsigned char c = p[i]; - outp[0] = '\\'; - outp[1] = 'x'; - outp[2] = Py_hexdigits[(c>>4)&0xf]; - outp[3] = Py_hexdigits[c&0xf]; - } - - assert(_PyUnicode_CheckConsistency(res, 1)); - Py_DECREF(object); - return Py_BuildValue("(Nn)", res, end); - } - if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeEncodeError)) { - if (PyUnicodeEncodeError_GetStart(exc, &start)) - return NULL; - if (PyUnicodeEncodeError_GetEnd(exc, &end)) - return NULL; - if (!(object = PyUnicodeEncodeError_GetObject(exc))) - return NULL; - } - else if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeTranslateError)) { - if (PyUnicodeTranslateError_GetStart(exc, &start)) - return NULL; - if (PyUnicodeTranslateError_GetEnd(exc, &end)) - return NULL; - if (!(object = PyUnicodeTranslateError_GetObject(exc))) - return NULL; - } - else { - wrong_exception_type(exc); - return NULL; - } - - if (end - start > PY_SSIZE_T_MAX / (1+1+8)) - end = start + PY_SSIZE_T_MAX / (1+1+8); - for (i = start, ressize = 0; i < end; ++i) { - /* object is guaranteed to be "ready" */ - c = PyUnicode_READ_CHAR(object, i); - if (c >= 0x10000) { - ressize += 1+1+8; - } - else if (c >= 0x100) { - ressize += 1+1+4; - } - else - ressize += 1+1+2; - } - res = PyUnicode_New(ressize, 127); - if (res == NULL) { - Py_DECREF(object); - return NULL; - } - outp = PyUnicode_1BYTE_DATA(res); - for (i = start; i < end; ++i) { - c = PyUnicode_READ_CHAR(object, i); - *outp++ = '\\'; - if (c >= 0x00010000) { - *outp++ = 'U'; - *outp++ = Py_hexdigits[(c>>28)&0xf]; - *outp++ = Py_hexdigits[(c>>24)&0xf]; - *outp++ = Py_hexdigits[(c>>20)&0xf]; - *outp++ = Py_hexdigits[(c>>16)&0xf]; - *outp++ = Py_hexdigits[(c>>12)&0xf]; - *outp++ = Py_hexdigits[(c>>8)&0xf]; - } - else if (c >= 0x100) { - *outp++ = 'u'; - *outp++ = Py_hexdigits[(c>>12)&0xf]; - *outp++ = Py_hexdigits[(c>>8)&0xf]; - } - else - *outp++ = 'x'; - *outp++ = Py_hexdigits[(c>>4)&0xf]; - *outp++ = Py_hexdigits[c&0xf]; - } - - assert(_PyUnicode_CheckConsistency(res, 1)); - Py_DECREF(object); - return Py_BuildValue("(Nn)", res, end); -} - -static _PyUnicode_Name_CAPI *ucnhash_capi = NULL; - -PyObject *PyCodec_NameReplaceErrors(PyObject *exc) -{ - if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeEncodeError)) { - PyObject *restuple; - PyObject *object; - Py_ssize_t i; - Py_ssize_t start; - Py_ssize_t end; - PyObject *res; - Py_UCS1 *outp; - Py_ssize_t ressize; - int replsize; - Py_UCS4 c; - char buffer[256]; /* NAME_MAXLEN */ - if (PyUnicodeEncodeError_GetStart(exc, &start)) - return NULL; - if (PyUnicodeEncodeError_GetEnd(exc, &end)) - return NULL; - if (!(object = PyUnicodeEncodeError_GetObject(exc))) - return NULL; - if (!ucnhash_capi) { - /* load the unicode data module */ - ucnhash_capi = (_PyUnicode_Name_CAPI *)PyCapsule_Import( - PyUnicodeData_CAPSULE_NAME, 1); - if (!ucnhash_capi) { - return NULL; - } - } - for (i = start, ressize = 0; i < end; ++i) { - /* object is guaranteed to be "ready" */ - c = PyUnicode_READ_CHAR(object, i); - if (ucnhash_capi->getname(c, buffer, sizeof(buffer), 1)) { - replsize = 1+1+1+(int)strlen(buffer)+1; - } - else if (c >= 0x10000) { - replsize = 1+1+8; - } - else if (c >= 0x100) { - replsize = 1+1+4; - } - else - replsize = 1+1+2; - if (ressize > PY_SSIZE_T_MAX - replsize) - break; - ressize += replsize; - } - end = i; - res = PyUnicode_New(ressize, 127); - if (res==NULL) - return NULL; - for (i = start, outp = PyUnicode_1BYTE_DATA(res); - i < end; ++i) { - c = PyUnicode_READ_CHAR(object, i); - *outp++ = '\\'; - if (ucnhash_capi->getname(c, buffer, sizeof(buffer), 1)) { - *outp++ = 'N'; - *outp++ = '{'; - strcpy((char *)outp, buffer); - outp += strlen(buffer); - *outp++ = '}'; - continue; - } - if (c >= 0x00010000) { - *outp++ = 'U'; - *outp++ = Py_hexdigits[(c>>28)&0xf]; - *outp++ = Py_hexdigits[(c>>24)&0xf]; - *outp++ = Py_hexdigits[(c>>20)&0xf]; - *outp++ = Py_hexdigits[(c>>16)&0xf]; - *outp++ = Py_hexdigits[(c>>12)&0xf]; - *outp++ = Py_hexdigits[(c>>8)&0xf]; - } - else if (c >= 0x100) { - *outp++ = 'u'; - *outp++ = Py_hexdigits[(c>>12)&0xf]; - *outp++ = Py_hexdigits[(c>>8)&0xf]; - } - else - *outp++ = 'x'; - *outp++ = Py_hexdigits[(c>>4)&0xf]; - *outp++ = Py_hexdigits[c&0xf]; - } - - assert(outp == PyUnicode_1BYTE_DATA(res) + ressize); - assert(_PyUnicode_CheckConsistency(res, 1)); - restuple = Py_BuildValue("(Nn)", res, end); - Py_DECREF(object); - return restuple; - } - else { - wrong_exception_type(exc); - return NULL; - } -} - -#define ENC_UNKNOWN -1 -#define ENC_UTF8 0 -#define ENC_UTF16BE 1 -#define ENC_UTF16LE 2 -#define ENC_UTF32BE 3 -#define ENC_UTF32LE 4 - -static int -get_standard_encoding(const char *encoding, int *bytelength) -{ - if (Py_TOLOWER(encoding[0]) == 'u' && - Py_TOLOWER(encoding[1]) == 't' && - Py_TOLOWER(encoding[2]) == 'f') { - encoding += 3; - if (*encoding == '-' || *encoding == '_' ) - encoding++; - if (encoding[0] == '8' && encoding[1] == '\0') { - *bytelength = 3; - return ENC_UTF8; - } - else if (encoding[0] == '1' && encoding[1] == '6') { - encoding += 2; - *bytelength = 2; - if (*encoding == '\0') { -#ifdef WORDS_BIGENDIAN - return ENC_UTF16BE; -#else - return ENC_UTF16LE; -#endif - } - if (*encoding == '-' || *encoding == '_' ) - encoding++; - if (Py_TOLOWER(encoding[1]) == 'e' && encoding[2] == '\0') { - if (Py_TOLOWER(encoding[0]) == 'b') - return ENC_UTF16BE; - if (Py_TOLOWER(encoding[0]) == 'l') - return ENC_UTF16LE; - } - } - else if (encoding[0] == '3' && encoding[1] == '2') { - encoding += 2; - *bytelength = 4; - if (*encoding == '\0') { -#ifdef WORDS_BIGENDIAN - return ENC_UTF32BE; -#else - return ENC_UTF32LE; -#endif - } - if (*encoding == '-' || *encoding == '_' ) - encoding++; - if (Py_TOLOWER(encoding[1]) == 'e' && encoding[2] == '\0') { - if (Py_TOLOWER(encoding[0]) == 'b') - return ENC_UTF32BE; - if (Py_TOLOWER(encoding[0]) == 'l') - return ENC_UTF32LE; - } - } - } - else if (strcmp(encoding, "CP_UTF8") == 0) { - *bytelength = 3; - return ENC_UTF8; - } - return ENC_UNKNOWN; -} - -/* This handler is declared static until someone demonstrates - a need to call it directly. */ -static PyObject * -PyCodec_SurrogatePassErrors(PyObject *exc) -{ - PyObject *restuple; - PyObject *object; - PyObject *encode; - const char *encoding; - int code; - int bytelength; - Py_ssize_t i; - Py_ssize_t start; - Py_ssize_t end; - PyObject *res; - - if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeEncodeError)) { - unsigned char *outp; - if (PyUnicodeEncodeError_GetStart(exc, &start)) - return NULL; - if (PyUnicodeEncodeError_GetEnd(exc, &end)) - return NULL; - if (!(object = PyUnicodeEncodeError_GetObject(exc))) - return NULL; - if (!(encode = PyUnicodeEncodeError_GetEncoding(exc))) { - Py_DECREF(object); - return NULL; - } - if (!(encoding = PyUnicode_AsUTF8(encode))) { - Py_DECREF(object); - Py_DECREF(encode); - return NULL; - } - code = get_standard_encoding(encoding, &bytelength); - Py_DECREF(encode); - if (code == ENC_UNKNOWN) { - /* Not supported, fail with original exception */ - PyErr_SetObject(PyExceptionInstance_Class(exc), exc); - Py_DECREF(object); - return NULL; - } - - if (end - start > PY_SSIZE_T_MAX / bytelength) - end = start + PY_SSIZE_T_MAX / bytelength; - res = PyBytes_FromStringAndSize(NULL, bytelength*(end-start)); - if (!res) { - Py_DECREF(object); - return NULL; - } - outp = (unsigned char*)PyBytes_AsString(res); - for (i = start; i < end; i++) { - /* object is guaranteed to be "ready" */ - Py_UCS4 ch = PyUnicode_READ_CHAR(object, i); - if (!Py_UNICODE_IS_SURROGATE(ch)) { - /* Not a surrogate, fail with original exception */ - PyErr_SetObject(PyExceptionInstance_Class(exc), exc); - Py_DECREF(res); - Py_DECREF(object); - return NULL; - } - switch (code) { - case ENC_UTF8: - *outp++ = (unsigned char)(0xe0 | (ch >> 12)); - *outp++ = (unsigned char)(0x80 | ((ch >> 6) & 0x3f)); - *outp++ = (unsigned char)(0x80 | (ch & 0x3f)); - break; - case ENC_UTF16LE: - *outp++ = (unsigned char) ch; - *outp++ = (unsigned char)(ch >> 8); - break; - case ENC_UTF16BE: - *outp++ = (unsigned char)(ch >> 8); - *outp++ = (unsigned char) ch; - break; - case ENC_UTF32LE: - *outp++ = (unsigned char) ch; - *outp++ = (unsigned char)(ch >> 8); - *outp++ = (unsigned char)(ch >> 16); - *outp++ = (unsigned char)(ch >> 24); - break; - case ENC_UTF32BE: - *outp++ = (unsigned char)(ch >> 24); - *outp++ = (unsigned char)(ch >> 16); - *outp++ = (unsigned char)(ch >> 8); - *outp++ = (unsigned char) ch; - break; - } - } - restuple = Py_BuildValue("(On)", res, end); - Py_DECREF(res); - Py_DECREF(object); - return restuple; - } - else if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeDecodeError)) { - const unsigned char *p; - Py_UCS4 ch = 0; - if (PyUnicodeDecodeError_GetStart(exc, &start)) - return NULL; - if (PyUnicodeDecodeError_GetEnd(exc, &end)) - return NULL; - if (!(object = PyUnicodeDecodeError_GetObject(exc))) - return NULL; - p = (const unsigned char*)PyBytes_AS_STRING(object); - if (!(encode = PyUnicodeDecodeError_GetEncoding(exc))) { - Py_DECREF(object); - return NULL; - } - if (!(encoding = PyUnicode_AsUTF8(encode))) { - Py_DECREF(object); - Py_DECREF(encode); - return NULL; - } - code = get_standard_encoding(encoding, &bytelength); - Py_DECREF(encode); - if (code == ENC_UNKNOWN) { - /* Not supported, fail with original exception */ - PyErr_SetObject(PyExceptionInstance_Class(exc), exc); - Py_DECREF(object); - return NULL; - } - - /* Try decoding a single surrogate character. If - there are more, let the codec call us again. */ - p += start; - if (PyBytes_GET_SIZE(object) - start >= bytelength) { - switch (code) { - case ENC_UTF8: - if ((p[0] & 0xf0) == 0xe0 && - (p[1] & 0xc0) == 0x80 && - (p[2] & 0xc0) == 0x80) { - /* it's a three-byte code */ - ch = ((p[0] & 0x0f) << 12) + ((p[1] & 0x3f) << 6) + (p[2] & 0x3f); - } - break; - case ENC_UTF16LE: - ch = p[1] << 8 | p[0]; - break; - case ENC_UTF16BE: - ch = p[0] << 8 | p[1]; - break; - case ENC_UTF32LE: - ch = (p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0]; - break; - case ENC_UTF32BE: - ch = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]; - break; - } - } - - Py_DECREF(object); - if (!Py_UNICODE_IS_SURROGATE(ch)) { - /* it's not a surrogate - fail */ - PyErr_SetObject(PyExceptionInstance_Class(exc), exc); - return NULL; - } - res = PyUnicode_FromOrdinal(ch); - if (res == NULL) - return NULL; - return Py_BuildValue("(Nn)", res, start + bytelength); - } - else { - wrong_exception_type(exc); - return NULL; - } -} - -static PyObject * -PyCodec_SurrogateEscapeErrors(PyObject *exc) -{ - PyObject *restuple; - PyObject *object; - Py_ssize_t i; - Py_ssize_t start; - Py_ssize_t end; - PyObject *res; - - if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeEncodeError)) { - char *outp; - if (PyUnicodeEncodeError_GetStart(exc, &start)) - return NULL; - if (PyUnicodeEncodeError_GetEnd(exc, &end)) - return NULL; - if (!(object = PyUnicodeEncodeError_GetObject(exc))) - return NULL; - res = PyBytes_FromStringAndSize(NULL, end-start); - if (!res) { - Py_DECREF(object); - return NULL; - } - outp = PyBytes_AsString(res); - for (i = start; i < end; i++) { - /* object is guaranteed to be "ready" */ - Py_UCS4 ch = PyUnicode_READ_CHAR(object, i); - if (ch < 0xdc80 || ch > 0xdcff) { - /* Not a UTF-8b surrogate, fail with original exception */ - PyErr_SetObject(PyExceptionInstance_Class(exc), exc); - Py_DECREF(res); - Py_DECREF(object); - return NULL; - } - *outp++ = ch - 0xdc00; - } - restuple = Py_BuildValue("(On)", res, end); - Py_DECREF(res); - Py_DECREF(object); - return restuple; - } - else if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeDecodeError)) { - PyObject *str; - const unsigned char *p; - Py_UCS2 ch[4]; /* decode up to 4 bad bytes. */ - int consumed = 0; - if (PyUnicodeDecodeError_GetStart(exc, &start)) - return NULL; - if (PyUnicodeDecodeError_GetEnd(exc, &end)) - return NULL; - if (!(object = PyUnicodeDecodeError_GetObject(exc))) - return NULL; - p = (const unsigned char*)PyBytes_AS_STRING(object); - while (consumed < 4 && consumed < end-start) { - /* Refuse to escape ASCII bytes. */ - if (p[start+consumed] < 128) - break; - ch[consumed] = 0xdc00 + p[start+consumed]; - consumed++; - } - Py_DECREF(object); - if (!consumed) { - /* codec complained about ASCII byte. */ - PyErr_SetObject(PyExceptionInstance_Class(exc), exc); - return NULL; - } - str = PyUnicode_FromKindAndData(PyUnicode_2BYTE_KIND, ch, consumed); - if (str == NULL) - return NULL; - return Py_BuildValue("(Nn)", str, start+consumed); - } - else { - wrong_exception_type(exc); - return NULL; - } -} - - -static PyObject *strict_errors(PyObject *self, PyObject *exc) -{ - return PyCodec_StrictErrors(exc); -} - - -static PyObject *ignore_errors(PyObject *self, PyObject *exc) -{ - return PyCodec_IgnoreErrors(exc); -} - - -static PyObject *replace_errors(PyObject *self, PyObject *exc) -{ - return PyCodec_ReplaceErrors(exc); -} - - -static PyObject *xmlcharrefreplace_errors(PyObject *self, PyObject *exc) -{ - return PyCodec_XMLCharRefReplaceErrors(exc); -} - - -static PyObject *backslashreplace_errors(PyObject *self, PyObject *exc) -{ - return PyCodec_BackslashReplaceErrors(exc); -} - -static PyObject *namereplace_errors(PyObject *self, PyObject *exc) -{ - return PyCodec_NameReplaceErrors(exc); -} - -static PyObject *surrogatepass_errors(PyObject *self, PyObject *exc) -{ - return PyCodec_SurrogatePassErrors(exc); -} - -static PyObject *surrogateescape_errors(PyObject *self, PyObject *exc) -{ - return PyCodec_SurrogateEscapeErrors(exc); -} - -static int _PyCodecRegistry_Init(void) -{ - static struct { - const char *name; - PyMethodDef def; - } methods[] = - { - { - "strict", - { - "strict_errors", - strict_errors, - METH_O, - PyDoc_STR("Implements the 'strict' error handling, which " - "raises a UnicodeError on coding errors.") - } - }, - { - "ignore", - { - "ignore_errors", - ignore_errors, - METH_O, - PyDoc_STR("Implements the 'ignore' error handling, which " - "ignores malformed data and continues.") - } - }, - { - "replace", - { - "replace_errors", - replace_errors, - METH_O, - PyDoc_STR("Implements the 'replace' error handling, which " - "replaces malformed data with a replacement marker.") - } - }, - { - "xmlcharrefreplace", - { - "xmlcharrefreplace_errors", - xmlcharrefreplace_errors, - METH_O, - PyDoc_STR("Implements the 'xmlcharrefreplace' error handling, " - "which replaces an unencodable character with the " - "appropriate XML character reference.") - } - }, - { - "backslashreplace", - { - "backslashreplace_errors", - backslashreplace_errors, - METH_O, - PyDoc_STR("Implements the 'backslashreplace' error handling, " - "which replaces malformed data with a backslashed " - "escape sequence.") - } - }, - { - "namereplace", - { - "namereplace_errors", - namereplace_errors, - METH_O, - PyDoc_STR("Implements the 'namereplace' error handling, " - "which replaces an unencodable character with a " - "\\N{...} escape sequence.") - } - }, - { - "surrogatepass", - { - "surrogatepass", - surrogatepass_errors, - METH_O - } - }, - { - "surrogateescape", - { - "surrogateescape", - surrogateescape_errors, - METH_O - } - } - }; - - PyInterpreterState *interp = _PyInterpreterState_GET(); - PyObject *mod; - - if (interp->codec_search_path != NULL) - return 0; - - interp->codec_search_path = PyList_New(0); - if (interp->codec_search_path == NULL) { - return -1; - } - - interp->codec_search_cache = PyDict_New(); - if (interp->codec_search_cache == NULL) { - return -1; - } - - interp->codec_error_registry = PyDict_New(); - if (interp->codec_error_registry == NULL) { - return -1; - } - - for (size_t i = 0; i < Py_ARRAY_LENGTH(methods); ++i) { - PyObject *func = PyCFunction_NewEx(&methods[i].def, NULL, NULL); - if (!func) { - return -1; - } - - int res = PyCodec_RegisterError(methods[i].name, func); - Py_DECREF(func); - if (res) { - return -1; - } - } - - mod = PyImport_ImportModuleNoBlock("encodings"); - if (mod == NULL) { - return -1; - } - Py_DECREF(mod); - interp->codecs_initialized = 1; - return 0; -} diff --git a/contrib/tools/python3/src/Python/compile.c b/contrib/tools/python3/src/Python/compile.c deleted file mode 100644 index 7210d42fc76..00000000000 --- a/contrib/tools/python3/src/Python/compile.c +++ /dev/null @@ -1,7918 +0,0 @@ -/* - * This file compiles an abstract syntax tree (AST) into Python bytecode. - * - * The primary entry point is _PyAST_Compile(), which returns a - * PyCodeObject. The compiler makes several passes to build the code - * object: - * 1. Checks for future statements. See future.c - * 2. Builds a symbol table. See symtable.c. - * 3. Generate code for basic blocks. See compiler_mod() in this file. - * 4. Assemble the basic blocks into final code. See assemble() in - * this file. - * 5. Optimize the byte code (peephole optimizations). - * - * Note that compiler_mod() suggests module, but the module ast type - * (mod_ty) has cases for expressions and interactive statements. - * - * CAUTION: The VISIT_* macros abort the current function when they - * encounter a problem. So don't invoke them when there is memory - * which needs to be released. Code blocks are OK, as the compiler - * structure takes care of releasing those. Use the arena to manage - * objects. - */ - -#include <stdbool.h> - -#include "Python.h" -#include "pycore_ast.h" // _PyAST_GetDocString() -#include "pycore_compile.h" // _PyFuture_FromAST() -#include "pycore_pymem.h" // _PyMem_IsPtrFreed() -#include "pycore_long.h" // _PyLong_GetZero() -#include "pycore_symtable.h" // PySTEntryObject - -#define NEED_OPCODE_JUMP_TABLES -#include "opcode.h" // EXTENDED_ARG -#include "wordcode_helpers.h" // instrsize() - - -#define DEFAULT_BLOCK_SIZE 16 -#define DEFAULT_BLOCKS 8 -#define DEFAULT_CODE_SIZE 128 -#define DEFAULT_LNOTAB_SIZE 16 - -#define COMP_GENEXP 0 -#define COMP_LISTCOMP 1 -#define COMP_SETCOMP 2 -#define COMP_DICTCOMP 3 - -/* A soft limit for stack use, to avoid excessive - * memory use for large constants, etc. - * - * The value 30 is plucked out of thin air. - * Code that could use more stack than this is - * rare, so the exact value is unimportant. - */ -#define STACK_USE_GUIDELINE 30 - -/* If we exceed this limit, it should - * be considered a compiler bug. - * Currently it should be impossible - * to exceed STACK_USE_GUIDELINE * 100, - * as 100 is the maximum parse depth. - * For performance reasons we will - * want to reduce this to a - * few hundred in the future. - * - * NOTE: Whatever MAX_ALLOWED_STACK_USE is - * set to, it should never restrict what Python - * we can write, just how we compile it. - */ -#define MAX_ALLOWED_STACK_USE (STACK_USE_GUIDELINE * 100) - -#define IS_TOP_LEVEL_AWAIT(c) ( \ - (c->c_flags->cf_flags & PyCF_ALLOW_TOP_LEVEL_AWAIT) \ - && (c->u->u_ste->ste_type == ModuleBlock)) - -struct instr { - unsigned char i_opcode; - int i_oparg; - struct basicblock_ *i_target; /* target block (if jump instruction) */ - int i_lineno; -}; - -#define LOG_BITS_PER_INT 5 -#define MASK_LOW_LOG_BITS 31 - -static inline int -is_bit_set_in_table(uint32_t *table, int bitindex) { - /* Is the relevant bit set in the relevant word? */ - /* 256 bits fit into 8 32-bits words. - * Word is indexed by (bitindex>>ln(size of int in bits)). - * Bit within word is the low bits of bitindex. - */ - uint32_t word = table[bitindex >> LOG_BITS_PER_INT]; - return (word >> (bitindex & MASK_LOW_LOG_BITS)) & 1; -} - -static inline int -is_relative_jump(struct instr *i) -{ - return is_bit_set_in_table(_PyOpcode_RelativeJump, i->i_opcode); -} - -static inline int -is_jump(struct instr *i) -{ - return is_bit_set_in_table(_PyOpcode_Jump, i->i_opcode); -} - -typedef struct basicblock_ { - /* Each basicblock in a compilation unit is linked via b_list in the - reverse order that the block are allocated. b_list points to the next - block, not to be confused with b_next, which is next by control flow. */ - struct basicblock_ *b_list; - /* number of instructions used */ - int b_iused; - /* length of instruction array (b_instr) */ - int b_ialloc; - /* pointer to an array of instructions, initially NULL */ - struct instr *b_instr; - /* If b_next is non-NULL, it is a pointer to the next - block reached by normal control flow. */ - struct basicblock_ *b_next; - /* b_return is true if a RETURN_VALUE opcode is inserted. */ - unsigned b_return : 1; - /* Number of predecssors that a block has. */ - int b_predecessors; - /* Basic block has no fall through (it ends with a return, raise or jump) */ - unsigned b_nofallthrough : 1; - /* Basic block exits scope (it ends with a return or raise) */ - unsigned b_exit : 1; - /* Used by compiler passes to mark whether they have visited a basic block. */ - unsigned b_visited : 1; - /* depth of stack upon entry of block, computed by stackdepth() */ - int b_startdepth; - /* instruction offset for block, computed by assemble_jump_offsets() */ - int b_offset; -} basicblock; - -/* fblockinfo tracks the current frame block. - -A frame block is used to handle loops, try/except, and try/finally. -It's called a frame block to distinguish it from a basic block in the -compiler IR. -*/ - -enum fblocktype { WHILE_LOOP, FOR_LOOP, TRY_EXCEPT, FINALLY_TRY, FINALLY_END, - WITH, ASYNC_WITH, HANDLER_CLEANUP, POP_VALUE, EXCEPTION_HANDLER, - ASYNC_COMPREHENSION_GENERATOR }; - -struct fblockinfo { - enum fblocktype fb_type; - basicblock *fb_block; - /* (optional) type-specific exit or cleanup block */ - basicblock *fb_exit; - /* (optional) additional information required for unwinding */ - void *fb_datum; -}; - -enum { - COMPILER_SCOPE_MODULE, - COMPILER_SCOPE_CLASS, - COMPILER_SCOPE_FUNCTION, - COMPILER_SCOPE_ASYNC_FUNCTION, - COMPILER_SCOPE_LAMBDA, - COMPILER_SCOPE_COMPREHENSION, -}; - -/* The following items change on entry and exit of code blocks. - They must be saved and restored when returning to a block. -*/ -struct compiler_unit { - PySTEntryObject *u_ste; - - PyObject *u_name; - PyObject *u_qualname; /* dot-separated qualified name (lazy) */ - int u_scope_type; - - /* The following fields are dicts that map objects to - the index of them in co_XXX. The index is used as - the argument for opcodes that refer to those collections. - */ - PyObject *u_consts; /* all constants */ - PyObject *u_names; /* all names */ - PyObject *u_varnames; /* local variables */ - PyObject *u_cellvars; /* cell variables */ - PyObject *u_freevars; /* free variables */ - - PyObject *u_private; /* for private name mangling */ - - Py_ssize_t u_argcount; /* number of arguments for block */ - Py_ssize_t u_posonlyargcount; /* number of positional only arguments for block */ - Py_ssize_t u_kwonlyargcount; /* number of keyword only arguments for block */ - /* Pointer to the most recently allocated block. By following b_list - members, you can reach all early allocated blocks. */ - basicblock *u_blocks; - basicblock *u_curblock; /* pointer to current block */ - - int u_nfblocks; - struct fblockinfo u_fblock[CO_MAXBLOCKS]; - - int u_firstlineno; /* the first lineno of the block */ - int u_lineno; /* the lineno for the current stmt */ - int u_col_offset; /* the offset of the current stmt */ - int u_end_lineno; /* the end line of the current stmt */ - int u_end_col_offset; /* the end offset of the current stmt */ -}; - -/* This struct captures the global state of a compilation. - -The u pointer points to the current compilation unit, while units -for enclosing blocks are stored in c_stack. The u and c_stack are -managed by compiler_enter_scope() and compiler_exit_scope(). - -Note that we don't track recursion levels during compilation - the -task of detecting and rejecting excessive levels of nesting is -handled by the symbol analysis pass. - -*/ - -struct compiler { - PyObject *c_filename; - struct symtable *c_st; - PyFutureFeatures *c_future; /* pointer to module's __future__ */ - PyCompilerFlags *c_flags; - - int c_optimize; /* optimization level */ - int c_interactive; /* true if in interactive mode */ - int c_nestlevel; - PyObject *c_const_cache; /* Python dict holding all constants, - including names tuple */ - struct compiler_unit *u; /* compiler state for current block */ - PyObject *c_stack; /* Python list holding compiler_unit ptrs */ - PyArena *c_arena; /* pointer to memory allocation arena */ -}; - -typedef struct { - // A list of strings corresponding to name captures. It is used to track: - // - Repeated name assignments in the same pattern. - // - Different name assignments in alternatives. - // - The order of name assignments in alternatives. - PyObject *stores; - // If 0, any name captures against our subject will raise. - int allow_irrefutable; - // An array of blocks to jump to on failure. Jumping to fail_pop[i] will pop - // i items off of the stack. The end result looks like this (with each block - // falling through to the next): - // fail_pop[4]: POP_TOP - // fail_pop[3]: POP_TOP - // fail_pop[2]: POP_TOP - // fail_pop[1]: POP_TOP - // fail_pop[0]: NOP - basicblock **fail_pop; - // The current length of fail_pop. - Py_ssize_t fail_pop_size; - // The number of items on top of the stack that need to *stay* on top of the - // stack. Variable captures go beneath these. All of them will be popped on - // failure. - Py_ssize_t on_top; -} pattern_context; - -static int compiler_enter_scope(struct compiler *, identifier, int, void *, int); -static void compiler_free(struct compiler *); -static basicblock *compiler_new_block(struct compiler *); -static int compiler_next_instr(basicblock *); -static int compiler_addop(struct compiler *, int); -static int compiler_addop_i(struct compiler *, int, Py_ssize_t); -static int compiler_addop_j(struct compiler *, int, basicblock *); -static int compiler_addop_j_noline(struct compiler *, int, basicblock *); -static int compiler_error(struct compiler *, const char *, ...); -static int compiler_warn(struct compiler *, const char *, ...); -static int compiler_nameop(struct compiler *, identifier, expr_context_ty); - -static PyCodeObject *compiler_mod(struct compiler *, mod_ty); -static int compiler_visit_stmt(struct compiler *, stmt_ty); -static int compiler_visit_keyword(struct compiler *, keyword_ty); -static int compiler_visit_expr(struct compiler *, expr_ty); -static int compiler_augassign(struct compiler *, stmt_ty); -static int compiler_annassign(struct compiler *, stmt_ty); -static int compiler_subscript(struct compiler *, expr_ty); -static int compiler_slice(struct compiler *, expr_ty); - -static int inplace_binop(operator_ty); -static int are_all_items_const(asdl_expr_seq *, Py_ssize_t, Py_ssize_t); - - -static int compiler_with(struct compiler *, stmt_ty, int); -static int compiler_async_with(struct compiler *, stmt_ty, int); -static int compiler_async_for(struct compiler *, stmt_ty); -static int compiler_call_helper(struct compiler *c, int n, - asdl_expr_seq *args, - asdl_keyword_seq *keywords); -static int compiler_try_except(struct compiler *, stmt_ty); -static int compiler_set_qualname(struct compiler *); - -static int compiler_sync_comprehension_generator( - struct compiler *c, - asdl_comprehension_seq *generators, int gen_index, - int depth, - expr_ty elt, expr_ty val, int type); - -static int compiler_async_comprehension_generator( - struct compiler *c, - asdl_comprehension_seq *generators, int gen_index, - int depth, - expr_ty elt, expr_ty val, int type); - -static int compiler_pattern(struct compiler *, pattern_ty, pattern_context *); -static int compiler_match(struct compiler *, stmt_ty); -static int compiler_pattern_subpattern(struct compiler *, pattern_ty, - pattern_context *); - -static PyCodeObject *assemble(struct compiler *, int addNone); -static PyObject *__doc__, *__annotations__; - -#define CAPSULE_NAME "compile.c compiler unit" - -PyObject * -_Py_Mangle(PyObject *privateobj, PyObject *ident) -{ - /* Name mangling: __private becomes _classname__private. - This is independent from how the name is used. */ - PyObject *result; - size_t nlen, plen, ipriv; - Py_UCS4 maxchar; - if (privateobj == NULL || !PyUnicode_Check(privateobj) || - PyUnicode_READ_CHAR(ident, 0) != '_' || - PyUnicode_READ_CHAR(ident, 1) != '_') { - Py_INCREF(ident); - return ident; - } - nlen = PyUnicode_GET_LENGTH(ident); - plen = PyUnicode_GET_LENGTH(privateobj); - /* Don't mangle __id__ or names with dots. - - The only time a name with a dot can occur is when - we are compiling an import statement that has a - package name. - - TODO(jhylton): Decide whether we want to support - mangling of the module name, e.g. __M.X. - */ - if ((PyUnicode_READ_CHAR(ident, nlen-1) == '_' && - PyUnicode_READ_CHAR(ident, nlen-2) == '_') || - PyUnicode_FindChar(ident, '.', 0, nlen, 1) != -1) { - Py_INCREF(ident); - return ident; /* Don't mangle __whatever__ */ - } - /* Strip leading underscores from class name */ - ipriv = 0; - while (PyUnicode_READ_CHAR(privateobj, ipriv) == '_') - ipriv++; - if (ipriv == plen) { - Py_INCREF(ident); - return ident; /* Don't mangle if class is just underscores */ - } - plen -= ipriv; - - if (plen + nlen >= PY_SSIZE_T_MAX - 1) { - PyErr_SetString(PyExc_OverflowError, - "private identifier too large to be mangled"); - return NULL; - } - - maxchar = PyUnicode_MAX_CHAR_VALUE(ident); - if (PyUnicode_MAX_CHAR_VALUE(privateobj) > maxchar) - maxchar = PyUnicode_MAX_CHAR_VALUE(privateobj); - - result = PyUnicode_New(1 + nlen + plen, maxchar); - if (!result) - return 0; - /* ident = "_" + priv[ipriv:] + ident # i.e. 1+plen+nlen bytes */ - PyUnicode_WRITE(PyUnicode_KIND(result), PyUnicode_DATA(result), 0, '_'); - if (PyUnicode_CopyCharacters(result, 1, privateobj, ipriv, plen) < 0) { - Py_DECREF(result); - return NULL; - } - if (PyUnicode_CopyCharacters(result, plen+1, ident, 0, nlen) < 0) { - Py_DECREF(result); - return NULL; - } - assert(_PyUnicode_CheckConsistency(result, 1)); - return result; -} - -static int -compiler_init(struct compiler *c) -{ - memset(c, 0, sizeof(struct compiler)); - - c->c_const_cache = PyDict_New(); - if (!c->c_const_cache) { - return 0; - } - - c->c_stack = PyList_New(0); - if (!c->c_stack) { - Py_CLEAR(c->c_const_cache); - return 0; - } - - return 1; -} - -PyCodeObject * -_PyAST_Compile(mod_ty mod, PyObject *filename, PyCompilerFlags *flags, - int optimize, PyArena *arena) -{ - struct compiler c; - PyCodeObject *co = NULL; - PyCompilerFlags local_flags = _PyCompilerFlags_INIT; - int merged; - - if (!__doc__) { - __doc__ = PyUnicode_InternFromString("__doc__"); - if (!__doc__) - return NULL; - } - if (!__annotations__) { - __annotations__ = PyUnicode_InternFromString("__annotations__"); - if (!__annotations__) - return NULL; - } - if (!compiler_init(&c)) - return NULL; - Py_INCREF(filename); - c.c_filename = filename; - c.c_arena = arena; - c.c_future = _PyFuture_FromAST(mod, filename); - if (c.c_future == NULL) - goto finally; - if (!flags) { - flags = &local_flags; - } - merged = c.c_future->ff_features | flags->cf_flags; - c.c_future->ff_features = merged; - flags->cf_flags = merged; - c.c_flags = flags; - c.c_optimize = (optimize == -1) ? _Py_GetConfig()->optimization_level : optimize; - c.c_nestlevel = 0; - - _PyASTOptimizeState state; - state.optimize = c.c_optimize; - state.ff_features = merged; - - if (!_PyAST_Optimize(mod, arena, &state)) { - goto finally; - } - - c.c_st = _PySymtable_Build(mod, filename, c.c_future); - if (c.c_st == NULL) { - if (!PyErr_Occurred()) - PyErr_SetString(PyExc_SystemError, "no symtable"); - goto finally; - } - - co = compiler_mod(&c, mod); - - finally: - compiler_free(&c); - assert(co || PyErr_Occurred()); - return co; -} - -static void -compiler_free(struct compiler *c) -{ - if (c->c_st) - _PySymtable_Free(c->c_st); - if (c->c_future) - PyObject_Free(c->c_future); - Py_XDECREF(c->c_filename); - Py_DECREF(c->c_const_cache); - Py_DECREF(c->c_stack); -} - -static PyObject * -list2dict(PyObject *list) -{ - Py_ssize_t i, n; - PyObject *v, *k; - PyObject *dict = PyDict_New(); - if (!dict) return NULL; - - n = PyList_Size(list); - for (i = 0; i < n; i++) { - v = PyLong_FromSsize_t(i); - if (!v) { - Py_DECREF(dict); - return NULL; - } - k = PyList_GET_ITEM(list, i); - if (PyDict_SetItem(dict, k, v) < 0) { - Py_DECREF(v); - Py_DECREF(dict); - return NULL; - } - Py_DECREF(v); - } - return dict; -} - -/* Return new dict containing names from src that match scope(s). - -src is a symbol table dictionary. If the scope of a name matches -either scope_type or flag is set, insert it into the new dict. The -values are integers, starting at offset and increasing by one for -each key. -*/ - -static PyObject * -dictbytype(PyObject *src, int scope_type, int flag, Py_ssize_t offset) -{ - Py_ssize_t i = offset, scope, num_keys, key_i; - PyObject *k, *v, *dest = PyDict_New(); - PyObject *sorted_keys; - - assert(offset >= 0); - if (dest == NULL) - return NULL; - - /* Sort the keys so that we have a deterministic order on the indexes - saved in the returned dictionary. These indexes are used as indexes - into the free and cell var storage. Therefore if they aren't - deterministic, then the generated bytecode is not deterministic. - */ - sorted_keys = PyDict_Keys(src); - if (sorted_keys == NULL) - return NULL; - if (PyList_Sort(sorted_keys) != 0) { - Py_DECREF(sorted_keys); - return NULL; - } - num_keys = PyList_GET_SIZE(sorted_keys); - - for (key_i = 0; key_i < num_keys; key_i++) { - /* XXX this should probably be a macro in symtable.h */ - long vi; - k = PyList_GET_ITEM(sorted_keys, key_i); - v = PyDict_GetItemWithError(src, k); - assert(v && PyLong_Check(v)); - vi = PyLong_AS_LONG(v); - scope = (vi >> SCOPE_OFFSET) & SCOPE_MASK; - - if (scope == scope_type || vi & flag) { - PyObject *item = PyLong_FromSsize_t(i); - if (item == NULL) { - Py_DECREF(sorted_keys); - Py_DECREF(dest); - return NULL; - } - i++; - if (PyDict_SetItem(dest, k, item) < 0) { - Py_DECREF(sorted_keys); - Py_DECREF(item); - Py_DECREF(dest); - return NULL; - } - Py_DECREF(item); - } - } - Py_DECREF(sorted_keys); - return dest; -} - -static void -compiler_unit_check(struct compiler_unit *u) -{ - basicblock *block; - for (block = u->u_blocks; block != NULL; block = block->b_list) { - assert(!_PyMem_IsPtrFreed(block)); - if (block->b_instr != NULL) { - assert(block->b_ialloc > 0); - assert(block->b_iused >= 0); - assert(block->b_ialloc >= block->b_iused); - } - else { - assert (block->b_iused == 0); - assert (block->b_ialloc == 0); - } - } -} - -static void -compiler_unit_free(struct compiler_unit *u) -{ - basicblock *b, *next; - - compiler_unit_check(u); - b = u->u_blocks; - while (b != NULL) { - if (b->b_instr) - PyObject_Free((void *)b->b_instr); - next = b->b_list; - PyObject_Free((void *)b); - b = next; - } - Py_CLEAR(u->u_ste); - Py_CLEAR(u->u_name); - Py_CLEAR(u->u_qualname); - Py_CLEAR(u->u_consts); - Py_CLEAR(u->u_names); - Py_CLEAR(u->u_varnames); - Py_CLEAR(u->u_freevars); - Py_CLEAR(u->u_cellvars); - Py_CLEAR(u->u_private); - PyObject_Free(u); -} - -static int -compiler_enter_scope(struct compiler *c, identifier name, - int scope_type, void *key, int lineno) -{ - struct compiler_unit *u; - basicblock *block; - - u = (struct compiler_unit *)PyObject_Calloc(1, sizeof( - struct compiler_unit)); - if (!u) { - PyErr_NoMemory(); - return 0; - } - u->u_scope_type = scope_type; - u->u_argcount = 0; - u->u_posonlyargcount = 0; - u->u_kwonlyargcount = 0; - u->u_ste = PySymtable_Lookup(c->c_st, key); - if (!u->u_ste) { - compiler_unit_free(u); - return 0; - } - Py_INCREF(name); - u->u_name = name; - u->u_varnames = list2dict(u->u_ste->ste_varnames); - u->u_cellvars = dictbytype(u->u_ste->ste_symbols, CELL, 0, 0); - if (!u->u_varnames || !u->u_cellvars) { - compiler_unit_free(u); - return 0; - } - if (u->u_ste->ste_needs_class_closure) { - /* Cook up an implicit __class__ cell. */ - _Py_IDENTIFIER(__class__); - PyObject *name; - int res; - assert(u->u_scope_type == COMPILER_SCOPE_CLASS); - assert(PyDict_GET_SIZE(u->u_cellvars) == 0); - name = _PyUnicode_FromId(&PyId___class__); - if (!name) { - compiler_unit_free(u); - return 0; - } - res = PyDict_SetItem(u->u_cellvars, name, _PyLong_GetZero()); - if (res < 0) { - compiler_unit_free(u); - return 0; - } - } - - u->u_freevars = dictbytype(u->u_ste->ste_symbols, FREE, DEF_FREE_CLASS, - PyDict_GET_SIZE(u->u_cellvars)); - if (!u->u_freevars) { - compiler_unit_free(u); - return 0; - } - - u->u_blocks = NULL; - u->u_nfblocks = 0; - u->u_firstlineno = lineno; - u->u_lineno = 0; - u->u_col_offset = 0; - u->u_end_lineno = 0; - u->u_end_col_offset = 0; - u->u_consts = PyDict_New(); - if (!u->u_consts) { - compiler_unit_free(u); - return 0; - } - u->u_names = PyDict_New(); - if (!u->u_names) { - compiler_unit_free(u); - return 0; - } - - u->u_private = NULL; - - /* Push the old compiler_unit on the stack. */ - if (c->u) { - PyObject *capsule = PyCapsule_New(c->u, CAPSULE_NAME, NULL); - if (!capsule || PyList_Append(c->c_stack, capsule) < 0) { - Py_XDECREF(capsule); - compiler_unit_free(u); - return 0; - } - Py_DECREF(capsule); - u->u_private = c->u->u_private; - Py_XINCREF(u->u_private); - } - c->u = u; - - c->c_nestlevel++; - - block = compiler_new_block(c); - if (block == NULL) - return 0; - c->u->u_curblock = block; - - if (u->u_scope_type != COMPILER_SCOPE_MODULE) { - if (!compiler_set_qualname(c)) - return 0; - } - - return 1; -} - -static void -compiler_exit_scope(struct compiler *c) -{ - // Don't call PySequence_DelItem() with an exception raised - PyObject *exc_type, *exc_val, *exc_tb; - PyErr_Fetch(&exc_type, &exc_val, &exc_tb); - - c->c_nestlevel--; - compiler_unit_free(c->u); - /* Restore c->u to the parent unit. */ - Py_ssize_t n = PyList_GET_SIZE(c->c_stack) - 1; - if (n >= 0) { - PyObject *capsule = PyList_GET_ITEM(c->c_stack, n); - c->u = (struct compiler_unit *)PyCapsule_GetPointer(capsule, CAPSULE_NAME); - assert(c->u); - /* we are deleting from a list so this really shouldn't fail */ - if (PySequence_DelItem(c->c_stack, n) < 0) { - _PyErr_WriteUnraisableMsg("on removing the last compiler " - "stack item", NULL); - } - compiler_unit_check(c->u); - } - else { - c->u = NULL; - } - - PyErr_Restore(exc_type, exc_val, exc_tb); -} - -static int -compiler_set_qualname(struct compiler *c) -{ - _Py_static_string(dot, "."); - _Py_static_string(dot_locals, ".<locals>"); - Py_ssize_t stack_size; - struct compiler_unit *u = c->u; - PyObject *name, *base, *dot_str, *dot_locals_str; - - base = NULL; - stack_size = PyList_GET_SIZE(c->c_stack); - assert(stack_size >= 1); - if (stack_size > 1) { - int scope, force_global = 0; - struct compiler_unit *parent; - PyObject *mangled, *capsule; - - capsule = PyList_GET_ITEM(c->c_stack, stack_size - 1); - parent = (struct compiler_unit *)PyCapsule_GetPointer(capsule, CAPSULE_NAME); - assert(parent); - - if (u->u_scope_type == COMPILER_SCOPE_FUNCTION - || u->u_scope_type == COMPILER_SCOPE_ASYNC_FUNCTION - || u->u_scope_type == COMPILER_SCOPE_CLASS) { - assert(u->u_name); - mangled = _Py_Mangle(parent->u_private, u->u_name); - if (!mangled) - return 0; - scope = _PyST_GetScope(parent->u_ste, mangled); - Py_DECREF(mangled); - assert(scope != GLOBAL_IMPLICIT); - if (scope == GLOBAL_EXPLICIT) - force_global = 1; - } - - if (!force_global) { - if (parent->u_scope_type == COMPILER_SCOPE_FUNCTION - || parent->u_scope_type == COMPILER_SCOPE_ASYNC_FUNCTION - || parent->u_scope_type == COMPILER_SCOPE_LAMBDA) { - dot_locals_str = _PyUnicode_FromId(&dot_locals); - if (dot_locals_str == NULL) - return 0; - base = PyUnicode_Concat(parent->u_qualname, dot_locals_str); - if (base == NULL) - return 0; - } - else { - Py_INCREF(parent->u_qualname); - base = parent->u_qualname; - } - } - } - - if (base != NULL) { - dot_str = _PyUnicode_FromId(&dot); - if (dot_str == NULL) { - Py_DECREF(base); - return 0; - } - name = PyUnicode_Concat(base, dot_str); - Py_DECREF(base); - if (name == NULL) - return 0; - PyUnicode_Append(&name, u->u_name); - if (name == NULL) - return 0; - } - else { - Py_INCREF(u->u_name); - name = u->u_name; - } - u->u_qualname = name; - - return 1; -} - - -/* Allocate a new block and return a pointer to it. - Returns NULL on error. -*/ - -static basicblock * -compiler_new_block(struct compiler *c) -{ - basicblock *b; - struct compiler_unit *u; - - u = c->u; - b = (basicblock *)PyObject_Calloc(1, sizeof(basicblock)); - if (b == NULL) { - PyErr_NoMemory(); - return NULL; - } - /* Extend the singly linked list of blocks with new block. */ - b->b_list = u->u_blocks; - u->u_blocks = b; - return b; -} - -static basicblock * -compiler_next_block(struct compiler *c) -{ - basicblock *block = compiler_new_block(c); - if (block == NULL) - return NULL; - c->u->u_curblock->b_next = block; - c->u->u_curblock = block; - return block; -} - -static basicblock * -compiler_use_next_block(struct compiler *c, basicblock *block) -{ - assert(block != NULL); - c->u->u_curblock->b_next = block; - c->u->u_curblock = block; - return block; -} - -static basicblock * -compiler_copy_block(struct compiler *c, basicblock *block) -{ - /* Cannot copy a block if it has a fallthrough, since - * a block can only have one fallthrough predecessor. - */ - assert(block->b_nofallthrough); - basicblock *result = compiler_new_block(c); - if (result == NULL) { - return NULL; - } - for (int i = 0; i < block->b_iused; i++) { - int n = compiler_next_instr(result); - if (n < 0) { - return NULL; - } - result->b_instr[n] = block->b_instr[i]; - } - result->b_exit = block->b_exit; - result->b_nofallthrough = 1; - return result; -} - -/* Returns the offset of the next instruction in the current block's - b_instr array. Resizes the b_instr as necessary. - Returns -1 on failure. -*/ - -static int -compiler_next_instr(basicblock *b) -{ - assert(b != NULL); - if (b->b_instr == NULL) { - b->b_instr = (struct instr *)PyObject_Calloc( - DEFAULT_BLOCK_SIZE, sizeof(struct instr)); - if (b->b_instr == NULL) { - PyErr_NoMemory(); - return -1; - } - b->b_ialloc = DEFAULT_BLOCK_SIZE; - } - else if (b->b_iused == b->b_ialloc) { - struct instr *tmp; - size_t oldsize, newsize; - oldsize = b->b_ialloc * sizeof(struct instr); - newsize = oldsize << 1; - - if (oldsize > (SIZE_MAX >> 1)) { - PyErr_NoMemory(); - return -1; - } - - if (newsize == 0) { - PyErr_NoMemory(); - return -1; - } - b->b_ialloc <<= 1; - tmp = (struct instr *)PyObject_Realloc( - (void *)b->b_instr, newsize); - if (tmp == NULL) { - PyErr_NoMemory(); - return -1; - } - b->b_instr = tmp; - memset((char *)b->b_instr + oldsize, 0, newsize - oldsize); - } - return b->b_iused++; -} - -/* Set the line number and column offset for the following instructions. - - The line number is reset in the following cases: - - when entering a new scope - - on each statement - - on each expression and sub-expression - - before the "except" and "finally" clauses -*/ - -#define SET_LOC(c, x) \ - (c)->u->u_lineno = (x)->lineno; \ - (c)->u->u_col_offset = (x)->col_offset; \ - (c)->u->u_end_lineno = (x)->end_lineno; \ - (c)->u->u_end_col_offset = (x)->end_col_offset; - -/* Return the stack effect of opcode with argument oparg. - - Some opcodes have different stack effect when jump to the target and - when not jump. The 'jump' parameter specifies the case: - - * 0 -- when not jump - * 1 -- when jump - * -1 -- maximal - */ -static int -stack_effect(int opcode, int oparg, int jump) -{ - switch (opcode) { - case NOP: - case EXTENDED_ARG: - return 0; - - /* Stack manipulation */ - case POP_TOP: - return -1; - case ROT_TWO: - case ROT_THREE: - case ROT_FOUR: - return 0; - case DUP_TOP: - return 1; - case DUP_TOP_TWO: - return 2; - - /* Unary operators */ - case UNARY_POSITIVE: - case UNARY_NEGATIVE: - case UNARY_NOT: - case UNARY_INVERT: - return 0; - - case SET_ADD: - case LIST_APPEND: - return -1; - case MAP_ADD: - return -2; - - /* Binary operators */ - case BINARY_POWER: - case BINARY_MULTIPLY: - case BINARY_MATRIX_MULTIPLY: - case BINARY_MODULO: - case BINARY_ADD: - case BINARY_SUBTRACT: - case BINARY_SUBSCR: - case BINARY_FLOOR_DIVIDE: - case BINARY_TRUE_DIVIDE: - return -1; - case INPLACE_FLOOR_DIVIDE: - case INPLACE_TRUE_DIVIDE: - return -1; - - case INPLACE_ADD: - case INPLACE_SUBTRACT: - case INPLACE_MULTIPLY: - case INPLACE_MATRIX_MULTIPLY: - case INPLACE_MODULO: - return -1; - case STORE_SUBSCR: - return -3; - case DELETE_SUBSCR: - return -2; - - case BINARY_LSHIFT: - case BINARY_RSHIFT: - case BINARY_AND: - case BINARY_XOR: - case BINARY_OR: - return -1; - case INPLACE_POWER: - return -1; - case GET_ITER: - return 0; - - case PRINT_EXPR: - return -1; - case LOAD_BUILD_CLASS: - return 1; - case INPLACE_LSHIFT: - case INPLACE_RSHIFT: - case INPLACE_AND: - case INPLACE_XOR: - case INPLACE_OR: - return -1; - - case SETUP_WITH: - /* 1 in the normal flow. - * Restore the stack position and push 6 values before jumping to - * the handler if an exception be raised. */ - return jump ? 6 : 1; - case RETURN_VALUE: - return -1; - case IMPORT_STAR: - return -1; - case SETUP_ANNOTATIONS: - return 0; - case YIELD_VALUE: - return 0; - case YIELD_FROM: - return -1; - case POP_BLOCK: - return 0; - case POP_EXCEPT: - return -3; - - case STORE_NAME: - return -1; - case DELETE_NAME: - return 0; - case UNPACK_SEQUENCE: - return oparg-1; - case UNPACK_EX: - return (oparg&0xFF) + (oparg>>8); - case FOR_ITER: - /* -1 at end of iterator, 1 if continue iterating. */ - return jump > 0 ? -1 : 1; - - case STORE_ATTR: - return -2; - case DELETE_ATTR: - return -1; - case STORE_GLOBAL: - return -1; - case DELETE_GLOBAL: - return 0; - case LOAD_CONST: - return 1; - case LOAD_NAME: - return 1; - case BUILD_TUPLE: - case BUILD_LIST: - case BUILD_SET: - case BUILD_STRING: - return 1-oparg; - case BUILD_MAP: - return 1 - 2*oparg; - case BUILD_CONST_KEY_MAP: - return -oparg; - case LOAD_ATTR: - return 0; - case COMPARE_OP: - case IS_OP: - case CONTAINS_OP: - return -1; - case JUMP_IF_NOT_EXC_MATCH: - return -2; - case IMPORT_NAME: - return -1; - case IMPORT_FROM: - return 1; - - /* Jumps */ - case JUMP_FORWARD: - case JUMP_ABSOLUTE: - return 0; - - case JUMP_IF_TRUE_OR_POP: - case JUMP_IF_FALSE_OR_POP: - return jump ? 0 : -1; - - case POP_JUMP_IF_FALSE: - case POP_JUMP_IF_TRUE: - return -1; - - case LOAD_GLOBAL: - return 1; - - /* Exception handling */ - case SETUP_FINALLY: - /* 0 in the normal flow. - * Restore the stack position and push 6 values before jumping to - * the handler if an exception be raised. */ - return jump ? 6 : 0; - case RERAISE: - return -3; - - case WITH_EXCEPT_START: - return 1; - - case LOAD_FAST: - return 1; - case STORE_FAST: - return -1; - case DELETE_FAST: - return 0; - - case RAISE_VARARGS: - return -oparg; - - /* Functions and calls */ - case CALL_FUNCTION: - return -oparg; - case CALL_METHOD: - return -oparg-1; - case CALL_FUNCTION_KW: - return -oparg-1; - case CALL_FUNCTION_EX: - return -1 - ((oparg & 0x01) != 0); - case MAKE_FUNCTION: - return -1 - ((oparg & 0x01) != 0) - ((oparg & 0x02) != 0) - - ((oparg & 0x04) != 0) - ((oparg & 0x08) != 0); - case BUILD_SLICE: - if (oparg == 3) - return -2; - else - return -1; - - /* Closures */ - case LOAD_CLOSURE: - return 1; - case LOAD_DEREF: - case LOAD_CLASSDEREF: - return 1; - case STORE_DEREF: - return -1; - case DELETE_DEREF: - return 0; - - /* Iterators and generators */ - case GET_AWAITABLE: - return 0; - case SETUP_ASYNC_WITH: - /* 0 in the normal flow. - * Restore the stack position to the position before the result - * of __aenter__ and push 6 values before jumping to the handler - * if an exception be raised. */ - return jump ? -1 + 6 : 0; - case BEFORE_ASYNC_WITH: - return 1; - case GET_AITER: - return 0; - case GET_ANEXT: - return 1; - case GET_YIELD_FROM_ITER: - return 0; - case END_ASYNC_FOR: - return -7; - case FORMAT_VALUE: - /* If there's a fmt_spec on the stack, we go from 2->1, - else 1->1. */ - return (oparg & FVS_MASK) == FVS_HAVE_SPEC ? -1 : 0; - case LOAD_METHOD: - return 1; - case LOAD_ASSERTION_ERROR: - return 1; - case LIST_TO_TUPLE: - return 0; - case GEN_START: - return -1; - case LIST_EXTEND: - case SET_UPDATE: - case DICT_MERGE: - case DICT_UPDATE: - return -1; - case COPY_DICT_WITHOUT_KEYS: - return 0; - case MATCH_CLASS: - return -1; - case GET_LEN: - case MATCH_MAPPING: - case MATCH_SEQUENCE: - return 1; - case MATCH_KEYS: - return 2; - case ROT_N: - return 0; - default: - return PY_INVALID_STACK_EFFECT; - } - return PY_INVALID_STACK_EFFECT; /* not reachable */ -} - -int -PyCompile_OpcodeStackEffectWithJump(int opcode, int oparg, int jump) -{ - return stack_effect(opcode, oparg, jump); -} - -int -PyCompile_OpcodeStackEffect(int opcode, int oparg) -{ - return stack_effect(opcode, oparg, -1); -} - -/* Add an opcode with no argument. - Returns 0 on failure, 1 on success. -*/ - -static int -compiler_addop_line(struct compiler *c, int opcode, int line) -{ - basicblock *b; - struct instr *i; - int off; - assert(!HAS_ARG(opcode)); - off = compiler_next_instr(c->u->u_curblock); - if (off < 0) - return 0; - b = c->u->u_curblock; - i = &b->b_instr[off]; - i->i_opcode = opcode; - i->i_oparg = 0; - if (opcode == RETURN_VALUE) - b->b_return = 1; - i->i_lineno = line; - return 1; -} - -static int -compiler_addop(struct compiler *c, int opcode) -{ - return compiler_addop_line(c, opcode, c->u->u_lineno); -} - -static int -compiler_addop_noline(struct compiler *c, int opcode) -{ - return compiler_addop_line(c, opcode, -1); -} - - -static Py_ssize_t -compiler_add_o(PyObject *dict, PyObject *o) -{ - PyObject *v; - Py_ssize_t arg; - - v = PyDict_GetItemWithError(dict, o); - if (!v) { - if (PyErr_Occurred()) { - return -1; - } - arg = PyDict_GET_SIZE(dict); - v = PyLong_FromSsize_t(arg); - if (!v) { - return -1; - } - if (PyDict_SetItem(dict, o, v) < 0) { - Py_DECREF(v); - return -1; - } - Py_DECREF(v); - } - else - arg = PyLong_AsLong(v); - return arg; -} - -// Merge const *o* recursively and return constant key object. -static PyObject* -merge_consts_recursive(struct compiler *c, PyObject *o) -{ - // None and Ellipsis are singleton, and key is the singleton. - // No need to merge object and key. - if (o == Py_None || o == Py_Ellipsis) { - Py_INCREF(o); - return o; - } - - PyObject *key = _PyCode_ConstantKey(o); - if (key == NULL) { - return NULL; - } - - // t is borrowed reference - PyObject *t = PyDict_SetDefault(c->c_const_cache, key, key); - if (t != key) { - // o is registered in c_const_cache. Just use it. - Py_XINCREF(t); - Py_DECREF(key); - return t; - } - - // We registered o in c_const_cache. - // When o is a tuple or frozenset, we want to merge its - // items too. - if (PyTuple_CheckExact(o)) { - Py_ssize_t len = PyTuple_GET_SIZE(o); - for (Py_ssize_t i = 0; i < len; i++) { - PyObject *item = PyTuple_GET_ITEM(o, i); - PyObject *u = merge_consts_recursive(c, item); - if (u == NULL) { - Py_DECREF(key); - return NULL; - } - - // See _PyCode_ConstantKey() - PyObject *v; // borrowed - if (PyTuple_CheckExact(u)) { - v = PyTuple_GET_ITEM(u, 1); - } - else { - v = u; - } - if (v != item) { - Py_INCREF(v); - PyTuple_SET_ITEM(o, i, v); - Py_DECREF(item); - } - - Py_DECREF(u); - } - } - else if (PyFrozenSet_CheckExact(o)) { - // *key* is tuple. And its first item is frozenset of - // constant keys. - // See _PyCode_ConstantKey() for detail. - assert(PyTuple_CheckExact(key)); - assert(PyTuple_GET_SIZE(key) == 2); - - Py_ssize_t len = PySet_GET_SIZE(o); - if (len == 0) { // empty frozenset should not be re-created. - return key; - } - PyObject *tuple = PyTuple_New(len); - if (tuple == NULL) { - Py_DECREF(key); - return NULL; - } - Py_ssize_t i = 0, pos = 0; - PyObject *item; - Py_hash_t hash; - while (_PySet_NextEntry(o, &pos, &item, &hash)) { - PyObject *k = merge_consts_recursive(c, item); - if (k == NULL) { - Py_DECREF(tuple); - Py_DECREF(key); - return NULL; - } - PyObject *u; - if (PyTuple_CheckExact(k)) { - u = PyTuple_GET_ITEM(k, 1); - Py_INCREF(u); - Py_DECREF(k); - } - else { - u = k; - } - PyTuple_SET_ITEM(tuple, i, u); // Steals reference of u. - i++; - } - - // Instead of rewriting o, we create new frozenset and embed in the - // key tuple. Caller should get merged frozenset from the key tuple. - PyObject *new = PyFrozenSet_New(tuple); - Py_DECREF(tuple); - if (new == NULL) { - Py_DECREF(key); - return NULL; - } - assert(PyTuple_GET_ITEM(key, 1) == o); - Py_DECREF(o); - PyTuple_SET_ITEM(key, 1, new); - } - - return key; -} - -static Py_ssize_t -compiler_add_const(struct compiler *c, PyObject *o) -{ - PyObject *key = merge_consts_recursive(c, o); - if (key == NULL) { - return -1; - } - - Py_ssize_t arg = compiler_add_o(c->u->u_consts, key); - Py_DECREF(key); - return arg; -} - -static int -compiler_addop_load_const(struct compiler *c, PyObject *o) -{ - Py_ssize_t arg = compiler_add_const(c, o); - if (arg < 0) - return 0; - return compiler_addop_i(c, LOAD_CONST, arg); -} - -static int -compiler_addop_o(struct compiler *c, int opcode, PyObject *dict, - PyObject *o) -{ - Py_ssize_t arg = compiler_add_o(dict, o); - if (arg < 0) - return 0; - return compiler_addop_i(c, opcode, arg); -} - -static int -compiler_addop_name(struct compiler *c, int opcode, PyObject *dict, - PyObject *o) -{ - Py_ssize_t arg; - - PyObject *mangled = _Py_Mangle(c->u->u_private, o); - if (!mangled) - return 0; - arg = compiler_add_o(dict, mangled); - Py_DECREF(mangled); - if (arg < 0) - return 0; - return compiler_addop_i(c, opcode, arg); -} - -/* Add an opcode with an integer argument. - Returns 0 on failure, 1 on success. -*/ - -static int -compiler_addop_i_line(struct compiler *c, int opcode, Py_ssize_t oparg, int lineno) -{ - struct instr *i; - int off; - - /* oparg value is unsigned, but a signed C int is usually used to store - it in the C code (like Python/ceval.c). - - Limit to 32-bit signed C int (rather than INT_MAX) for portability. - - The argument of a concrete bytecode instruction is limited to 8-bit. - EXTENDED_ARG is used for 16, 24, and 32-bit arguments. */ - assert(HAS_ARG(opcode)); - assert(0 <= oparg && oparg <= 2147483647); - - off = compiler_next_instr(c->u->u_curblock); - if (off < 0) - return 0; - i = &c->u->u_curblock->b_instr[off]; - i->i_opcode = opcode; - i->i_oparg = Py_SAFE_DOWNCAST(oparg, Py_ssize_t, int); - i->i_lineno = lineno; - return 1; -} - -static int -compiler_addop_i(struct compiler *c, int opcode, Py_ssize_t oparg) -{ - return compiler_addop_i_line(c, opcode, oparg, c->u->u_lineno); -} - -static int -compiler_addop_i_noline(struct compiler *c, int opcode, Py_ssize_t oparg) -{ - return compiler_addop_i_line(c, opcode, oparg, -1); -} - -static int add_jump_to_block(basicblock *b, int opcode, int lineno, basicblock *target) -{ - assert(HAS_ARG(opcode)); - assert(b != NULL); - assert(target != NULL); - - int off = compiler_next_instr(b); - struct instr *i = &b->b_instr[off]; - if (off < 0) { - return 0; - } - i->i_opcode = opcode; - i->i_target = target; - i->i_lineno = lineno; - return 1; -} - -static int -compiler_addop_j(struct compiler *c, int opcode, basicblock *b) -{ - return add_jump_to_block(c->u->u_curblock, opcode, c->u->u_lineno, b); -} - -static int -compiler_addop_j_noline(struct compiler *c, int opcode, basicblock *b) -{ - return add_jump_to_block(c->u->u_curblock, opcode, -1, b); -} - -/* NEXT_BLOCK() creates an implicit jump from the current block - to the new block. - - The returns inside this macro make it impossible to decref objects - created in the local function. Local objects should use the arena. -*/ -#define NEXT_BLOCK(C) { \ - if (compiler_next_block((C)) == NULL) \ - return 0; \ -} - -#define ADDOP(C, OP) { \ - if (!compiler_addop((C), (OP))) \ - return 0; \ -} - -#define ADDOP_NOLINE(C, OP) { \ - if (!compiler_addop_noline((C), (OP))) \ - return 0; \ -} - -#define ADDOP_IN_SCOPE(C, OP) { \ - if (!compiler_addop((C), (OP))) { \ - compiler_exit_scope(c); \ - return 0; \ - } \ -} - -#define ADDOP_LOAD_CONST(C, O) { \ - if (!compiler_addop_load_const((C), (O))) \ - return 0; \ -} - -/* Same as ADDOP_LOAD_CONST, but steals a reference. */ -#define ADDOP_LOAD_CONST_NEW(C, O) { \ - PyObject *__new_const = (O); \ - if (__new_const == NULL) { \ - return 0; \ - } \ - if (!compiler_addop_load_const((C), __new_const)) { \ - Py_DECREF(__new_const); \ - return 0; \ - } \ - Py_DECREF(__new_const); \ -} - -#define ADDOP_O(C, OP, O, TYPE) { \ - assert((OP) != LOAD_CONST); /* use ADDOP_LOAD_CONST */ \ - if (!compiler_addop_o((C), (OP), (C)->u->u_ ## TYPE, (O))) \ - return 0; \ -} - -/* Same as ADDOP_O, but steals a reference. */ -#define ADDOP_N(C, OP, O, TYPE) { \ - assert((OP) != LOAD_CONST); /* use ADDOP_LOAD_CONST_NEW */ \ - if (!compiler_addop_o((C), (OP), (C)->u->u_ ## TYPE, (O))) { \ - Py_DECREF((O)); \ - return 0; \ - } \ - Py_DECREF((O)); \ -} - -#define ADDOP_NAME(C, OP, O, TYPE) { \ - if (!compiler_addop_name((C), (OP), (C)->u->u_ ## TYPE, (O))) \ - return 0; \ -} - -#define ADDOP_I(C, OP, O) { \ - if (!compiler_addop_i((C), (OP), (O))) \ - return 0; \ -} - -#define ADDOP_I_NOLINE(C, OP, O) { \ - if (!compiler_addop_i_noline((C), (OP), (O))) \ - return 0; \ -} - -#define ADDOP_JUMP(C, OP, O) { \ - if (!compiler_addop_j((C), (OP), (O))) \ - return 0; \ -} - -/* Add a jump with no line number. - * Used for artificial jumps that have no corresponding - * token in the source code. */ -#define ADDOP_JUMP_NOLINE(C, OP, O) { \ - if (!compiler_addop_j_noline((C), (OP), (O))) \ - return 0; \ -} - -#define ADDOP_COMPARE(C, CMP) { \ - if (!compiler_addcompare((C), (cmpop_ty)(CMP))) \ - return 0; \ -} - -/* VISIT and VISIT_SEQ takes an ASDL type as their second argument. They use - the ASDL name to synthesize the name of the C type and the visit function. -*/ - -#define VISIT(C, TYPE, V) {\ - if (!compiler_visit_ ## TYPE((C), (V))) \ - return 0; \ -} - -#define VISIT_IN_SCOPE(C, TYPE, V) {\ - if (!compiler_visit_ ## TYPE((C), (V))) { \ - compiler_exit_scope(c); \ - return 0; \ - } \ -} - -#define VISIT_SLICE(C, V, CTX) {\ - if (!compiler_visit_slice((C), (V), (CTX))) \ - return 0; \ -} - -#define VISIT_SEQ(C, TYPE, SEQ) { \ - int _i; \ - asdl_ ## TYPE ## _seq *seq = (SEQ); /* avoid variable capture */ \ - for (_i = 0; _i < asdl_seq_LEN(seq); _i++) { \ - TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, _i); \ - if (!compiler_visit_ ## TYPE((C), elt)) \ - return 0; \ - } \ -} - -#define VISIT_SEQ_IN_SCOPE(C, TYPE, SEQ) { \ - int _i; \ - asdl_ ## TYPE ## _seq *seq = (SEQ); /* avoid variable capture */ \ - for (_i = 0; _i < asdl_seq_LEN(seq); _i++) { \ - TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, _i); \ - if (!compiler_visit_ ## TYPE((C), elt)) { \ - compiler_exit_scope(c); \ - return 0; \ - } \ - } \ -} - -#define RETURN_IF_FALSE(X) \ - if (!(X)) { \ - return 0; \ - } - -/* Search if variable annotations are present statically in a block. */ - -static int -find_ann(asdl_stmt_seq *stmts) -{ - int i, j, res = 0; - stmt_ty st; - - for (i = 0; i < asdl_seq_LEN(stmts); i++) { - st = (stmt_ty)asdl_seq_GET(stmts, i); - switch (st->kind) { - case AnnAssign_kind: - return 1; - case For_kind: - res = find_ann(st->v.For.body) || - find_ann(st->v.For.orelse); - break; - case AsyncFor_kind: - res = find_ann(st->v.AsyncFor.body) || - find_ann(st->v.AsyncFor.orelse); - break; - case While_kind: - res = find_ann(st->v.While.body) || - find_ann(st->v.While.orelse); - break; - case If_kind: - res = find_ann(st->v.If.body) || - find_ann(st->v.If.orelse); - break; - case With_kind: - res = find_ann(st->v.With.body); - break; - case AsyncWith_kind: - res = find_ann(st->v.AsyncWith.body); - break; - case Try_kind: - for (j = 0; j < asdl_seq_LEN(st->v.Try.handlers); j++) { - excepthandler_ty handler = (excepthandler_ty)asdl_seq_GET( - st->v.Try.handlers, j); - if (find_ann(handler->v.ExceptHandler.body)) { - return 1; - } - } - res = find_ann(st->v.Try.body) || - find_ann(st->v.Try.finalbody) || - find_ann(st->v.Try.orelse); - break; - default: - res = 0; - } - if (res) { - break; - } - } - return res; -} - -/* - * Frame block handling functions - */ - -static int -compiler_push_fblock(struct compiler *c, enum fblocktype t, basicblock *b, - basicblock *exit, void *datum) -{ - struct fblockinfo *f; - if (c->u->u_nfblocks >= CO_MAXBLOCKS) { - return compiler_error(c, "too many statically nested blocks"); - } - f = &c->u->u_fblock[c->u->u_nfblocks++]; - f->fb_type = t; - f->fb_block = b; - f->fb_exit = exit; - f->fb_datum = datum; - return 1; -} - -static void -compiler_pop_fblock(struct compiler *c, enum fblocktype t, basicblock *b) -{ - struct compiler_unit *u = c->u; - assert(u->u_nfblocks > 0); - u->u_nfblocks--; - assert(u->u_fblock[u->u_nfblocks].fb_type == t); - assert(u->u_fblock[u->u_nfblocks].fb_block == b); -} - -static int -compiler_call_exit_with_nones(struct compiler *c) { - ADDOP_LOAD_CONST(c, Py_None); - ADDOP(c, DUP_TOP); - ADDOP(c, DUP_TOP); - ADDOP_I(c, CALL_FUNCTION, 3); - return 1; -} - -/* Unwind a frame block. If preserve_tos is true, the TOS before - * popping the blocks will be restored afterwards, unless another - * return, break or continue is found. In which case, the TOS will - * be popped. - */ -static int -compiler_unwind_fblock(struct compiler *c, struct fblockinfo *info, - int preserve_tos) -{ - switch (info->fb_type) { - case WHILE_LOOP: - case EXCEPTION_HANDLER: - case ASYNC_COMPREHENSION_GENERATOR: - return 1; - - case FOR_LOOP: - /* Pop the iterator */ - if (preserve_tos) { - ADDOP(c, ROT_TWO); - } - ADDOP(c, POP_TOP); - return 1; - - case TRY_EXCEPT: - ADDOP(c, POP_BLOCK); - return 1; - - case FINALLY_TRY: - /* This POP_BLOCK gets the line number of the unwinding statement */ - ADDOP(c, POP_BLOCK); - if (preserve_tos) { - if (!compiler_push_fblock(c, POP_VALUE, NULL, NULL, NULL)) { - return 0; - } - } - /* Emit the finally block */ - VISIT_SEQ(c, stmt, info->fb_datum); - if (preserve_tos) { - compiler_pop_fblock(c, POP_VALUE, NULL); - } - /* The finally block should appear to execute after the - * statement causing the unwinding, so make the unwinding - * instruction artificial */ - c->u->u_lineno = -1; - return 1; - - case FINALLY_END: - if (preserve_tos) { - ADDOP(c, ROT_FOUR); - } - ADDOP(c, POP_TOP); - ADDOP(c, POP_TOP); - ADDOP(c, POP_TOP); - if (preserve_tos) { - ADDOP(c, ROT_FOUR); - } - ADDOP(c, POP_EXCEPT); - return 1; - - case WITH: - case ASYNC_WITH: - SET_LOC(c, (stmt_ty)info->fb_datum); - ADDOP(c, POP_BLOCK); - if (preserve_tos) { - ADDOP(c, ROT_TWO); - } - if(!compiler_call_exit_with_nones(c)) { - return 0; - } - if (info->fb_type == ASYNC_WITH) { - ADDOP(c, GET_AWAITABLE); - ADDOP_LOAD_CONST(c, Py_None); - ADDOP(c, YIELD_FROM); - } - ADDOP(c, POP_TOP); - /* The exit block should appear to execute after the - * statement causing the unwinding, so make the unwinding - * instruction artificial */ - c->u->u_lineno = -1; - return 1; - - case HANDLER_CLEANUP: - if (info->fb_datum) { - ADDOP(c, POP_BLOCK); - } - if (preserve_tos) { - ADDOP(c, ROT_FOUR); - } - ADDOP(c, POP_EXCEPT); - if (info->fb_datum) { - ADDOP_LOAD_CONST(c, Py_None); - compiler_nameop(c, info->fb_datum, Store); - compiler_nameop(c, info->fb_datum, Del); - } - return 1; - - case POP_VALUE: - if (preserve_tos) { - ADDOP(c, ROT_TWO); - } - ADDOP(c, POP_TOP); - return 1; - } - Py_UNREACHABLE(); -} - -/** Unwind block stack. If loop is not NULL, then stop when the first loop is encountered. */ -static int -compiler_unwind_fblock_stack(struct compiler *c, int preserve_tos, struct fblockinfo **loop) { - if (c->u->u_nfblocks == 0) { - return 1; - } - struct fblockinfo *top = &c->u->u_fblock[c->u->u_nfblocks-1]; - if (loop != NULL && (top->fb_type == WHILE_LOOP || top->fb_type == FOR_LOOP)) { - *loop = top; - return 1; - } - struct fblockinfo copy = *top; - c->u->u_nfblocks--; - if (!compiler_unwind_fblock(c, ©, preserve_tos)) { - return 0; - } - if (!compiler_unwind_fblock_stack(c, preserve_tos, loop)) { - return 0; - } - c->u->u_fblock[c->u->u_nfblocks] = copy; - c->u->u_nfblocks++; - return 1; -} - -/* Compile a sequence of statements, checking for a docstring - and for annotations. */ - -static int -compiler_body(struct compiler *c, asdl_stmt_seq *stmts) -{ - int i = 0; - stmt_ty st; - PyObject *docstring; - - /* Set current line number to the line number of first statement. - This way line number for SETUP_ANNOTATIONS will always - coincide with the line number of first "real" statement in module. - If body is empty, then lineno will be set later in assemble. */ - if (c->u->u_scope_type == COMPILER_SCOPE_MODULE && asdl_seq_LEN(stmts)) { - st = (stmt_ty)asdl_seq_GET(stmts, 0); - SET_LOC(c, st); - } - /* Every annotated class and module should have __annotations__. */ - if (find_ann(stmts)) { - ADDOP(c, SETUP_ANNOTATIONS); - } - if (!asdl_seq_LEN(stmts)) - return 1; - /* if not -OO mode, set docstring */ - if (c->c_optimize < 2) { - docstring = _PyAST_GetDocString(stmts); - if (docstring) { - i = 1; - st = (stmt_ty)asdl_seq_GET(stmts, 0); - assert(st->kind == Expr_kind); - VISIT(c, expr, st->v.Expr.value); - if (!compiler_nameop(c, __doc__, Store)) - return 0; - } - } - for (; i < asdl_seq_LEN(stmts); i++) - VISIT(c, stmt, (stmt_ty)asdl_seq_GET(stmts, i)); - return 1; -} - -static PyCodeObject * -compiler_mod(struct compiler *c, mod_ty mod) -{ - PyCodeObject *co; - int addNone = 1; - static PyObject *module; - if (!module) { - module = PyUnicode_InternFromString("<module>"); - if (!module) - return NULL; - } - /* Use 0 for firstlineno initially, will fixup in assemble(). */ - if (!compiler_enter_scope(c, module, COMPILER_SCOPE_MODULE, mod, 1)) - return NULL; - switch (mod->kind) { - case Module_kind: - if (!compiler_body(c, mod->v.Module.body)) { - compiler_exit_scope(c); - return 0; - } - break; - case Interactive_kind: - if (find_ann(mod->v.Interactive.body)) { - ADDOP(c, SETUP_ANNOTATIONS); - } - c->c_interactive = 1; - VISIT_SEQ_IN_SCOPE(c, stmt, mod->v.Interactive.body); - break; - case Expression_kind: - VISIT_IN_SCOPE(c, expr, mod->v.Expression.body); - addNone = 0; - break; - default: - PyErr_Format(PyExc_SystemError, - "module kind %d should not be possible", - mod->kind); - return 0; - } - co = assemble(c, addNone); - compiler_exit_scope(c); - return co; -} - -/* The test for LOCAL must come before the test for FREE in order to - handle classes where name is both local and free. The local var is - a method and the free var is a free var referenced within a method. -*/ - -static int -get_ref_type(struct compiler *c, PyObject *name) -{ - int scope; - if (c->u->u_scope_type == COMPILER_SCOPE_CLASS && - _PyUnicode_EqualToASCIIString(name, "__class__")) - return CELL; - scope = _PyST_GetScope(c->u->u_ste, name); - if (scope == 0) { - PyErr_Format(PyExc_SystemError, - "_PyST_GetScope(name=%R) failed: " - "unknown scope in unit %S (%R); " - "symbols: %R; locals: %R; globals: %R", - name, - c->u->u_name, c->u->u_ste->ste_id, - c->u->u_ste->ste_symbols, c->u->u_varnames, c->u->u_names); - return -1; - } - return scope; -} - -static int -compiler_lookup_arg(PyObject *dict, PyObject *name) -{ - PyObject *v; - v = PyDict_GetItemWithError(dict, name); - if (v == NULL) - return -1; - return PyLong_AS_LONG(v); -} - -static int -compiler_make_closure(struct compiler *c, PyCodeObject *co, Py_ssize_t flags, - PyObject *qualname) -{ - Py_ssize_t i, free = PyCode_GetNumFree(co); - if (qualname == NULL) - qualname = co->co_name; - - if (free) { - for (i = 0; i < free; ++i) { - /* Bypass com_addop_varname because it will generate - LOAD_DEREF but LOAD_CLOSURE is needed. - */ - PyObject *name = PyTuple_GET_ITEM(co->co_freevars, i); - - /* Special case: If a class contains a method with a - free variable that has the same name as a method, - the name will be considered free *and* local in the - class. It should be handled by the closure, as - well as by the normal name lookup logic. - */ - int reftype = get_ref_type(c, name); - if (reftype == -1) { - return 0; - } - int arg; - if (reftype == CELL) { - arg = compiler_lookup_arg(c->u->u_cellvars, name); - } - else { - arg = compiler_lookup_arg(c->u->u_freevars, name); - } - if (arg == -1) { - PyErr_Format(PyExc_SystemError, - "compiler_lookup_arg(name=%R) with reftype=%d failed in %S; " - "freevars of code %S: %R", - name, - reftype, - c->u->u_name, - co->co_name, - co->co_freevars); - return 0; - } - ADDOP_I(c, LOAD_CLOSURE, arg); - } - flags |= 0x08; - ADDOP_I(c, BUILD_TUPLE, free); - } - ADDOP_LOAD_CONST(c, (PyObject*)co); - ADDOP_LOAD_CONST(c, qualname); - ADDOP_I(c, MAKE_FUNCTION, flags); - return 1; -} - -static int -compiler_decorators(struct compiler *c, asdl_expr_seq* decos) -{ - int i; - - if (!decos) - return 1; - - for (i = 0; i < asdl_seq_LEN(decos); i++) { - VISIT(c, expr, (expr_ty)asdl_seq_GET(decos, i)); - } - return 1; -} - -static int -compiler_visit_kwonlydefaults(struct compiler *c, asdl_arg_seq *kwonlyargs, - asdl_expr_seq *kw_defaults) -{ - /* Push a dict of keyword-only default values. - - Return 0 on error, -1 if no dict pushed, 1 if a dict is pushed. - */ - int i; - PyObject *keys = NULL; - - for (i = 0; i < asdl_seq_LEN(kwonlyargs); i++) { - arg_ty arg = asdl_seq_GET(kwonlyargs, i); - expr_ty default_ = asdl_seq_GET(kw_defaults, i); - if (default_) { - PyObject *mangled = _Py_Mangle(c->u->u_private, arg->arg); - if (!mangled) { - goto error; - } - if (keys == NULL) { - keys = PyList_New(1); - if (keys == NULL) { - Py_DECREF(mangled); - return 0; - } - PyList_SET_ITEM(keys, 0, mangled); - } - else { - int res = PyList_Append(keys, mangled); - Py_DECREF(mangled); - if (res == -1) { - goto error; - } - } - if (!compiler_visit_expr(c, default_)) { - goto error; - } - } - } - if (keys != NULL) { - Py_ssize_t default_count = PyList_GET_SIZE(keys); - PyObject *keys_tuple = PyList_AsTuple(keys); - Py_DECREF(keys); - ADDOP_LOAD_CONST_NEW(c, keys_tuple); - ADDOP_I(c, BUILD_CONST_KEY_MAP, default_count); - assert(default_count > 0); - return 1; - } - else { - return -1; - } - -error: - Py_XDECREF(keys); - return 0; -} - -static int -compiler_visit_annexpr(struct compiler *c, expr_ty annotation) -{ - ADDOP_LOAD_CONST_NEW(c, _PyAST_ExprAsUnicode(annotation)); - return 1; -} - -static int -compiler_visit_argannotation(struct compiler *c, identifier id, - expr_ty annotation, Py_ssize_t *annotations_len) -{ - if (!annotation) { - return 1; - } - - PyObject *mangled = _Py_Mangle(c->u->u_private, id); - if (!mangled) { - return 0; - } - ADDOP_LOAD_CONST(c, mangled); - Py_DECREF(mangled); - - if (c->c_future->ff_features & CO_FUTURE_ANNOTATIONS) { - VISIT(c, annexpr, annotation) - } - else { - VISIT(c, expr, annotation); - } - *annotations_len += 2; - return 1; -} - -static int -compiler_visit_argannotations(struct compiler *c, asdl_arg_seq* args, - Py_ssize_t *annotations_len) -{ - int i; - for (i = 0; i < asdl_seq_LEN(args); i++) { - arg_ty arg = (arg_ty)asdl_seq_GET(args, i); - if (!compiler_visit_argannotation( - c, - arg->arg, - arg->annotation, - annotations_len)) - return 0; - } - return 1; -} - -static int -compiler_visit_annotations(struct compiler *c, arguments_ty args, - expr_ty returns) -{ - /* Push arg annotation names and values. - The expressions are evaluated out-of-order wrt the source code. - - Return 0 on error, -1 if no annotations pushed, 1 if a annotations is pushed. - */ - static identifier return_str; - Py_ssize_t annotations_len = 0; - - if (!compiler_visit_argannotations(c, args->args, &annotations_len)) - return 0; - if (!compiler_visit_argannotations(c, args->posonlyargs, &annotations_len)) - return 0; - if (args->vararg && args->vararg->annotation && - !compiler_visit_argannotation(c, args->vararg->arg, - args->vararg->annotation, &annotations_len)) - return 0; - if (!compiler_visit_argannotations(c, args->kwonlyargs, &annotations_len)) - return 0; - if (args->kwarg && args->kwarg->annotation && - !compiler_visit_argannotation(c, args->kwarg->arg, - args->kwarg->annotation, &annotations_len)) - return 0; - - if (!return_str) { - return_str = PyUnicode_InternFromString("return"); - if (!return_str) - return 0; - } - if (!compiler_visit_argannotation(c, return_str, returns, &annotations_len)) { - return 0; - } - - if (annotations_len) { - ADDOP_I(c, BUILD_TUPLE, annotations_len); - return 1; - } - - return -1; -} - -static int -compiler_visit_defaults(struct compiler *c, arguments_ty args) -{ - VISIT_SEQ(c, expr, args->defaults); - ADDOP_I(c, BUILD_TUPLE, asdl_seq_LEN(args->defaults)); - return 1; -} - -static Py_ssize_t -compiler_default_arguments(struct compiler *c, arguments_ty args) -{ - Py_ssize_t funcflags = 0; - if (args->defaults && asdl_seq_LEN(args->defaults) > 0) { - if (!compiler_visit_defaults(c, args)) - return -1; - funcflags |= 0x01; - } - if (args->kwonlyargs) { - int res = compiler_visit_kwonlydefaults(c, args->kwonlyargs, - args->kw_defaults); - if (res == 0) { - return -1; - } - else if (res > 0) { - funcflags |= 0x02; - } - } - return funcflags; -} - -static int -forbidden_name(struct compiler *c, identifier name, expr_context_ty ctx) -{ - - if (ctx == Store && _PyUnicode_EqualToASCIIString(name, "__debug__")) { - compiler_error(c, "cannot assign to __debug__"); - return 1; - } - if (ctx == Del && _PyUnicode_EqualToASCIIString(name, "__debug__")) { - compiler_error(c, "cannot delete __debug__"); - return 1; - } - return 0; -} - -static int -compiler_check_debug_one_arg(struct compiler *c, arg_ty arg) -{ - if (arg != NULL) { - if (forbidden_name(c, arg->arg, Store)) - return 0; - } - return 1; -} - -static int -compiler_check_debug_args_seq(struct compiler *c, asdl_arg_seq *args) -{ - if (args != NULL) { - for (Py_ssize_t i = 0, n = asdl_seq_LEN(args); i < n; i++) { - if (!compiler_check_debug_one_arg(c, asdl_seq_GET(args, i))) - return 0; - } - } - return 1; -} - -static int -compiler_check_debug_args(struct compiler *c, arguments_ty args) -{ - if (!compiler_check_debug_args_seq(c, args->posonlyargs)) - return 0; - if (!compiler_check_debug_args_seq(c, args->args)) - return 0; - if (!compiler_check_debug_one_arg(c, args->vararg)) - return 0; - if (!compiler_check_debug_args_seq(c, args->kwonlyargs)) - return 0; - if (!compiler_check_debug_one_arg(c, args->kwarg)) - return 0; - return 1; -} - -static int -compiler_function(struct compiler *c, stmt_ty s, int is_async) -{ - PyCodeObject *co; - PyObject *qualname, *docstring = NULL; - arguments_ty args; - expr_ty returns; - identifier name; - asdl_expr_seq* decos; - asdl_stmt_seq *body; - Py_ssize_t i, funcflags; - int annotations; - int scope_type; - int firstlineno; - - if (is_async) { - assert(s->kind == AsyncFunctionDef_kind); - - args = s->v.AsyncFunctionDef.args; - returns = s->v.AsyncFunctionDef.returns; - decos = s->v.AsyncFunctionDef.decorator_list; - name = s->v.AsyncFunctionDef.name; - body = s->v.AsyncFunctionDef.body; - - scope_type = COMPILER_SCOPE_ASYNC_FUNCTION; - } else { - assert(s->kind == FunctionDef_kind); - - args = s->v.FunctionDef.args; - returns = s->v.FunctionDef.returns; - decos = s->v.FunctionDef.decorator_list; - name = s->v.FunctionDef.name; - body = s->v.FunctionDef.body; - - scope_type = COMPILER_SCOPE_FUNCTION; - } - - if (!compiler_check_debug_args(c, args)) - return 0; - - if (!compiler_decorators(c, decos)) - return 0; - - firstlineno = s->lineno; - if (asdl_seq_LEN(decos)) { - firstlineno = ((expr_ty)asdl_seq_GET(decos, 0))->lineno; - } - - funcflags = compiler_default_arguments(c, args); - if (funcflags == -1) { - return 0; - } - - annotations = compiler_visit_annotations(c, args, returns); - if (annotations == 0) { - return 0; - } - else if (annotations > 0) { - funcflags |= 0x04; - } - - if (!compiler_enter_scope(c, name, scope_type, (void *)s, firstlineno)) { - return 0; - } - - /* if not -OO mode, add docstring */ - if (c->c_optimize < 2) { - docstring = _PyAST_GetDocString(body); - } - if (compiler_add_const(c, docstring ? docstring : Py_None) < 0) { - compiler_exit_scope(c); - return 0; - } - - c->u->u_argcount = asdl_seq_LEN(args->args); - c->u->u_posonlyargcount = asdl_seq_LEN(args->posonlyargs); - c->u->u_kwonlyargcount = asdl_seq_LEN(args->kwonlyargs); - for (i = docstring ? 1 : 0; i < asdl_seq_LEN(body); i++) { - VISIT_IN_SCOPE(c, stmt, (stmt_ty)asdl_seq_GET(body, i)); - } - co = assemble(c, 1); - qualname = c->u->u_qualname; - Py_INCREF(qualname); - compiler_exit_scope(c); - if (co == NULL) { - Py_XDECREF(qualname); - Py_XDECREF(co); - return 0; - } - - if (!compiler_make_closure(c, co, funcflags, qualname)) { - Py_DECREF(qualname); - Py_DECREF(co); - return 0; - } - Py_DECREF(qualname); - Py_DECREF(co); - - /* decorators */ - for (i = 0; i < asdl_seq_LEN(decos); i++) { - ADDOP_I(c, CALL_FUNCTION, 1); - } - - return compiler_nameop(c, name, Store); -} - -static int -compiler_class(struct compiler *c, stmt_ty s) -{ - PyCodeObject *co; - PyObject *str; - int i, firstlineno; - asdl_expr_seq *decos = s->v.ClassDef.decorator_list; - - if (!compiler_decorators(c, decos)) - return 0; - - firstlineno = s->lineno; - if (asdl_seq_LEN(decos)) { - firstlineno = ((expr_ty)asdl_seq_GET(decos, 0))->lineno; - } - - /* ultimately generate code for: - <name> = __build_class__(<func>, <name>, *<bases>, **<keywords>) - where: - <func> is a zero arg function/closure created from the class body. - It mutates its locals to build the class namespace. - <name> is the class name - <bases> is the positional arguments and *varargs argument - <keywords> is the keyword arguments and **kwds argument - This borrows from compiler_call. - */ - - /* 1. compile the class body into a code object */ - if (!compiler_enter_scope(c, s->v.ClassDef.name, - COMPILER_SCOPE_CLASS, (void *)s, firstlineno)) - return 0; - /* this block represents what we do in the new scope */ - { - /* use the class name for name mangling */ - Py_INCREF(s->v.ClassDef.name); - Py_XSETREF(c->u->u_private, s->v.ClassDef.name); - /* load (global) __name__ ... */ - str = PyUnicode_InternFromString("__name__"); - if (!str || !compiler_nameop(c, str, Load)) { - Py_XDECREF(str); - compiler_exit_scope(c); - return 0; - } - Py_DECREF(str); - /* ... and store it as __module__ */ - str = PyUnicode_InternFromString("__module__"); - if (!str || !compiler_nameop(c, str, Store)) { - Py_XDECREF(str); - compiler_exit_scope(c); - return 0; - } - Py_DECREF(str); - assert(c->u->u_qualname); - ADDOP_LOAD_CONST(c, c->u->u_qualname); - str = PyUnicode_InternFromString("__qualname__"); - if (!str || !compiler_nameop(c, str, Store)) { - Py_XDECREF(str); - compiler_exit_scope(c); - return 0; - } - Py_DECREF(str); - /* compile the body proper */ - if (!compiler_body(c, s->v.ClassDef.body)) { - compiler_exit_scope(c); - return 0; - } - /* The following code is artificial */ - c->u->u_lineno = -1; - /* Return __classcell__ if it is referenced, otherwise return None */ - if (c->u->u_ste->ste_needs_class_closure) { - /* Store __classcell__ into class namespace & return it */ - str = PyUnicode_InternFromString("__class__"); - if (str == NULL) { - compiler_exit_scope(c); - return 0; - } - i = compiler_lookup_arg(c->u->u_cellvars, str); - Py_DECREF(str); - if (i < 0) { - compiler_exit_scope(c); - return 0; - } - assert(i == 0); - - ADDOP_I(c, LOAD_CLOSURE, i); - ADDOP(c, DUP_TOP); - str = PyUnicode_InternFromString("__classcell__"); - if (!str || !compiler_nameop(c, str, Store)) { - Py_XDECREF(str); - compiler_exit_scope(c); - return 0; - } - Py_DECREF(str); - } - else { - /* No methods referenced __class__, so just return None */ - assert(PyDict_GET_SIZE(c->u->u_cellvars) == 0); - ADDOP_LOAD_CONST(c, Py_None); - } - ADDOP_IN_SCOPE(c, RETURN_VALUE); - /* create the code object */ - co = assemble(c, 1); - } - /* leave the new scope */ - compiler_exit_scope(c); - if (co == NULL) - return 0; - - /* 2. load the 'build_class' function */ - ADDOP(c, LOAD_BUILD_CLASS); - - /* 3. load a function (or closure) made from the code object */ - if (!compiler_make_closure(c, co, 0, NULL)) { - Py_DECREF(co); - return 0; - } - Py_DECREF(co); - - /* 4. load class name */ - ADDOP_LOAD_CONST(c, s->v.ClassDef.name); - - /* 5. generate the rest of the code for the call */ - if (!compiler_call_helper(c, 2, s->v.ClassDef.bases, s->v.ClassDef.keywords)) - return 0; - - /* 6. apply decorators */ - for (i = 0; i < asdl_seq_LEN(decos); i++) { - ADDOP_I(c, CALL_FUNCTION, 1); - } - - /* 7. store into <name> */ - if (!compiler_nameop(c, s->v.ClassDef.name, Store)) - return 0; - return 1; -} - -/* Return 0 if the expression is a constant value except named singletons. - Return 1 otherwise. */ -static int -check_is_arg(expr_ty e) -{ - if (e->kind != Constant_kind) { - return 1; - } - PyObject *value = e->v.Constant.value; - return (value == Py_None - || value == Py_False - || value == Py_True - || value == Py_Ellipsis); -} - -/* Check operands of identity chacks ("is" and "is not"). - Emit a warning if any operand is a constant except named singletons. - Return 0 on error. - */ -static int -check_compare(struct compiler *c, expr_ty e) -{ - Py_ssize_t i, n; - int left = check_is_arg(e->v.Compare.left); - n = asdl_seq_LEN(e->v.Compare.ops); - for (i = 0; i < n; i++) { - cmpop_ty op = (cmpop_ty)asdl_seq_GET(e->v.Compare.ops, i); - int right = check_is_arg((expr_ty)asdl_seq_GET(e->v.Compare.comparators, i)); - if (op == Is || op == IsNot) { - if (!right || !left) { - const char *msg = (op == Is) - ? "\"is\" with a literal. Did you mean \"==\"?" - : "\"is not\" with a literal. Did you mean \"!=\"?"; - return compiler_warn(c, msg); - } - } - left = right; - } - return 1; -} - -static int compiler_addcompare(struct compiler *c, cmpop_ty op) -{ - int cmp; - switch (op) { - case Eq: - cmp = Py_EQ; - break; - case NotEq: - cmp = Py_NE; - break; - case Lt: - cmp = Py_LT; - break; - case LtE: - cmp = Py_LE; - break; - case Gt: - cmp = Py_GT; - break; - case GtE: - cmp = Py_GE; - break; - case Is: - ADDOP_I(c, IS_OP, 0); - return 1; - case IsNot: - ADDOP_I(c, IS_OP, 1); - return 1; - case In: - ADDOP_I(c, CONTAINS_OP, 0); - return 1; - case NotIn: - ADDOP_I(c, CONTAINS_OP, 1); - return 1; - default: - Py_UNREACHABLE(); - } - ADDOP_I(c, COMPARE_OP, cmp); - return 1; -} - - - -static int -compiler_jump_if(struct compiler *c, expr_ty e, basicblock *next, int cond) -{ - switch (e->kind) { - case UnaryOp_kind: - if (e->v.UnaryOp.op == Not) - return compiler_jump_if(c, e->v.UnaryOp.operand, next, !cond); - /* fallback to general implementation */ - break; - case BoolOp_kind: { - asdl_expr_seq *s = e->v.BoolOp.values; - Py_ssize_t i, n = asdl_seq_LEN(s) - 1; - assert(n >= 0); - int cond2 = e->v.BoolOp.op == Or; - basicblock *next2 = next; - if (!cond2 != !cond) { - next2 = compiler_new_block(c); - if (next2 == NULL) - return 0; - } - for (i = 0; i < n; ++i) { - if (!compiler_jump_if(c, (expr_ty)asdl_seq_GET(s, i), next2, cond2)) - return 0; - } - if (!compiler_jump_if(c, (expr_ty)asdl_seq_GET(s, n), next, cond)) - return 0; - if (next2 != next) - compiler_use_next_block(c, next2); - return 1; - } - case IfExp_kind: { - basicblock *end, *next2; - end = compiler_new_block(c); - if (end == NULL) - return 0; - next2 = compiler_new_block(c); - if (next2 == NULL) - return 0; - if (!compiler_jump_if(c, e->v.IfExp.test, next2, 0)) - return 0; - if (!compiler_jump_if(c, e->v.IfExp.body, next, cond)) - return 0; - ADDOP_JUMP_NOLINE(c, JUMP_FORWARD, end); - compiler_use_next_block(c, next2); - if (!compiler_jump_if(c, e->v.IfExp.orelse, next, cond)) - return 0; - compiler_use_next_block(c, end); - return 1; - } - case Compare_kind: { - Py_ssize_t i, n = asdl_seq_LEN(e->v.Compare.ops) - 1; - if (n > 0) { - if (!check_compare(c, e)) { - return 0; - } - basicblock *cleanup = compiler_new_block(c); - if (cleanup == NULL) - return 0; - VISIT(c, expr, e->v.Compare.left); - for (i = 0; i < n; i++) { - VISIT(c, expr, - (expr_ty)asdl_seq_GET(e->v.Compare.comparators, i)); - ADDOP(c, DUP_TOP); - ADDOP(c, ROT_THREE); - ADDOP_COMPARE(c, asdl_seq_GET(e->v.Compare.ops, i)); - ADDOP_JUMP(c, POP_JUMP_IF_FALSE, cleanup); - NEXT_BLOCK(c); - } - VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Compare.comparators, n)); - ADDOP_COMPARE(c, asdl_seq_GET(e->v.Compare.ops, n)); - ADDOP_JUMP(c, cond ? POP_JUMP_IF_TRUE : POP_JUMP_IF_FALSE, next); - NEXT_BLOCK(c); - basicblock *end = compiler_new_block(c); - if (end == NULL) - return 0; - ADDOP_JUMP_NOLINE(c, JUMP_FORWARD, end); - compiler_use_next_block(c, cleanup); - ADDOP(c, POP_TOP); - if (!cond) { - ADDOP_JUMP_NOLINE(c, JUMP_FORWARD, next); - } - compiler_use_next_block(c, end); - return 1; - } - /* fallback to general implementation */ - break; - } - default: - /* fallback to general implementation */ - break; - } - - /* general implementation */ - VISIT(c, expr, e); - ADDOP_JUMP(c, cond ? POP_JUMP_IF_TRUE : POP_JUMP_IF_FALSE, next); - NEXT_BLOCK(c); - return 1; -} - -static int -compiler_ifexp(struct compiler *c, expr_ty e) -{ - basicblock *end, *next; - - assert(e->kind == IfExp_kind); - end = compiler_new_block(c); - if (end == NULL) - return 0; - next = compiler_new_block(c); - if (next == NULL) - return 0; - if (!compiler_jump_if(c, e->v.IfExp.test, next, 0)) - return 0; - VISIT(c, expr, e->v.IfExp.body); - ADDOP_JUMP_NOLINE(c, JUMP_FORWARD, end); - compiler_use_next_block(c, next); - VISIT(c, expr, e->v.IfExp.orelse); - compiler_use_next_block(c, end); - return 1; -} - -static int -compiler_lambda(struct compiler *c, expr_ty e) -{ - PyCodeObject *co; - PyObject *qualname; - static identifier name; - Py_ssize_t funcflags; - arguments_ty args = e->v.Lambda.args; - assert(e->kind == Lambda_kind); - - if (!compiler_check_debug_args(c, args)) - return 0; - - if (!name) { - name = PyUnicode_InternFromString("<lambda>"); - if (!name) - return 0; - } - - funcflags = compiler_default_arguments(c, args); - if (funcflags == -1) { - return 0; - } - - if (!compiler_enter_scope(c, name, COMPILER_SCOPE_LAMBDA, - (void *)e, e->lineno)) - return 0; - - /* Make None the first constant, so the lambda can't have a - docstring. */ - if (compiler_add_const(c, Py_None) < 0) - return 0; - - c->u->u_argcount = asdl_seq_LEN(args->args); - c->u->u_posonlyargcount = asdl_seq_LEN(args->posonlyargs); - c->u->u_kwonlyargcount = asdl_seq_LEN(args->kwonlyargs); - VISIT_IN_SCOPE(c, expr, e->v.Lambda.body); - if (c->u->u_ste->ste_generator) { - co = assemble(c, 0); - } - else { - ADDOP_IN_SCOPE(c, RETURN_VALUE); - co = assemble(c, 1); - } - qualname = c->u->u_qualname; - Py_INCREF(qualname); - compiler_exit_scope(c); - if (co == NULL) { - Py_DECREF(qualname); - return 0; - } - - if (!compiler_make_closure(c, co, funcflags, qualname)) { - Py_DECREF(qualname); - Py_DECREF(co); - return 0; - } - Py_DECREF(qualname); - Py_DECREF(co); - - return 1; -} - -static int -compiler_if(struct compiler *c, stmt_ty s) -{ - basicblock *end, *next; - assert(s->kind == If_kind); - end = compiler_new_block(c); - if (end == NULL) { - return 0; - } - if (asdl_seq_LEN(s->v.If.orelse)) { - next = compiler_new_block(c); - if (next == NULL) { - return 0; - } - } - else { - next = end; - } - if (!compiler_jump_if(c, s->v.If.test, next, 0)) { - return 0; - } - VISIT_SEQ(c, stmt, s->v.If.body); - if (asdl_seq_LEN(s->v.If.orelse)) { - ADDOP_JUMP_NOLINE(c, JUMP_FORWARD, end); - compiler_use_next_block(c, next); - VISIT_SEQ(c, stmt, s->v.If.orelse); - } - compiler_use_next_block(c, end); - return 1; -} - -static int -compiler_for(struct compiler *c, stmt_ty s) -{ - basicblock *start, *body, *cleanup, *end; - - start = compiler_new_block(c); - body = compiler_new_block(c); - cleanup = compiler_new_block(c); - end = compiler_new_block(c); - if (start == NULL || body == NULL || end == NULL || cleanup == NULL) { - return 0; - } - if (!compiler_push_fblock(c, FOR_LOOP, start, end, NULL)) { - return 0; - } - VISIT(c, expr, s->v.For.iter); - ADDOP(c, GET_ITER); - compiler_use_next_block(c, start); - ADDOP_JUMP(c, FOR_ITER, cleanup); - compiler_use_next_block(c, body); - VISIT(c, expr, s->v.For.target); - VISIT_SEQ(c, stmt, s->v.For.body); - /* Mark jump as artificial */ - c->u->u_lineno = -1; - ADDOP_JUMP(c, JUMP_ABSOLUTE, start); - compiler_use_next_block(c, cleanup); - - compiler_pop_fblock(c, FOR_LOOP, start); - - VISIT_SEQ(c, stmt, s->v.For.orelse); - compiler_use_next_block(c, end); - return 1; -} - - -static int -compiler_async_for(struct compiler *c, stmt_ty s) -{ - basicblock *start, *except, *end; - if (IS_TOP_LEVEL_AWAIT(c)){ - c->u->u_ste->ste_coroutine = 1; - } else if (c->u->u_scope_type != COMPILER_SCOPE_ASYNC_FUNCTION) { - return compiler_error(c, "'async for' outside async function"); - } - - start = compiler_new_block(c); - except = compiler_new_block(c); - end = compiler_new_block(c); - - if (start == NULL || except == NULL || end == NULL) { - return 0; - } - VISIT(c, expr, s->v.AsyncFor.iter); - ADDOP(c, GET_AITER); - - compiler_use_next_block(c, start); - if (!compiler_push_fblock(c, FOR_LOOP, start, end, NULL)) { - return 0; - } - /* SETUP_FINALLY to guard the __anext__ call */ - ADDOP_JUMP(c, SETUP_FINALLY, except); - ADDOP(c, GET_ANEXT); - ADDOP_LOAD_CONST(c, Py_None); - ADDOP(c, YIELD_FROM); - ADDOP(c, POP_BLOCK); /* for SETUP_FINALLY */ - - /* Success block for __anext__ */ - VISIT(c, expr, s->v.AsyncFor.target); - VISIT_SEQ(c, stmt, s->v.AsyncFor.body); - /* Mark jump as artificial */ - c->u->u_lineno = -1; - ADDOP_JUMP(c, JUMP_ABSOLUTE, start); - - compiler_pop_fblock(c, FOR_LOOP, start); - - /* Except block for __anext__ */ - compiler_use_next_block(c, except); - - /* Use same line number as the iterator, - * as the END_ASYNC_FOR succeeds the `for`, not the body. */ - SET_LOC(c, s->v.AsyncFor.iter); - ADDOP(c, END_ASYNC_FOR); - - /* `else` block */ - VISIT_SEQ(c, stmt, s->v.For.orelse); - - compiler_use_next_block(c, end); - - return 1; -} - -static int -compiler_while(struct compiler *c, stmt_ty s) -{ - basicblock *loop, *body, *end, *anchor = NULL; - loop = compiler_new_block(c); - body = compiler_new_block(c); - anchor = compiler_new_block(c); - end = compiler_new_block(c); - if (loop == NULL || body == NULL || anchor == NULL || end == NULL) { - return 0; - } - compiler_use_next_block(c, loop); - if (!compiler_push_fblock(c, WHILE_LOOP, loop, end, NULL)) { - return 0; - } - if (!compiler_jump_if(c, s->v.While.test, anchor, 0)) { - return 0; - } - - compiler_use_next_block(c, body); - VISIT_SEQ(c, stmt, s->v.While.body); - SET_LOC(c, s); - if (!compiler_jump_if(c, s->v.While.test, body, 1)) { - return 0; - } - - compiler_pop_fblock(c, WHILE_LOOP, loop); - - compiler_use_next_block(c, anchor); - if (s->v.While.orelse) { - VISIT_SEQ(c, stmt, s->v.While.orelse); - } - compiler_use_next_block(c, end); - - return 1; -} - -static int -compiler_return(struct compiler *c, stmt_ty s) -{ - int preserve_tos = ((s->v.Return.value != NULL) && - (s->v.Return.value->kind != Constant_kind)); - if (c->u->u_ste->ste_type != FunctionBlock) - return compiler_error(c, "'return' outside function"); - if (s->v.Return.value != NULL && - c->u->u_ste->ste_coroutine && c->u->u_ste->ste_generator) - { - return compiler_error( - c, "'return' with value in async generator"); - } - if (preserve_tos) { - VISIT(c, expr, s->v.Return.value); - } else { - /* Emit instruction with line number for return value */ - if (s->v.Return.value != NULL) { - SET_LOC(c, s->v.Return.value); - ADDOP(c, NOP); - } - } - if (s->v.Return.value == NULL || s->v.Return.value->lineno != s->lineno) { - SET_LOC(c, s); - ADDOP(c, NOP); - } - - if (!compiler_unwind_fblock_stack(c, preserve_tos, NULL)) - return 0; - if (s->v.Return.value == NULL) { - ADDOP_LOAD_CONST(c, Py_None); - } - else if (!preserve_tos) { - ADDOP_LOAD_CONST(c, s->v.Return.value->v.Constant.value); - } - ADDOP(c, RETURN_VALUE); - NEXT_BLOCK(c); - - return 1; -} - -static int -compiler_break(struct compiler *c) -{ - struct fblockinfo *loop = NULL; - /* Emit instruction with line number */ - ADDOP(c, NOP); - if (!compiler_unwind_fblock_stack(c, 0, &loop)) { - return 0; - } - if (loop == NULL) { - return compiler_error(c, "'break' outside loop"); - } - if (!compiler_unwind_fblock(c, loop, 0)) { - return 0; - } - ADDOP_JUMP(c, JUMP_ABSOLUTE, loop->fb_exit); - NEXT_BLOCK(c); - return 1; -} - -static int -compiler_continue(struct compiler *c) -{ - struct fblockinfo *loop = NULL; - /* Emit instruction with line number */ - ADDOP(c, NOP); - if (!compiler_unwind_fblock_stack(c, 0, &loop)) { - return 0; - } - if (loop == NULL) { - return compiler_error(c, "'continue' not properly in loop"); - } - ADDOP_JUMP(c, JUMP_ABSOLUTE, loop->fb_block); - NEXT_BLOCK(c) - return 1; -} - - -/* Code generated for "try: <body> finally: <finalbody>" is as follows: - - SETUP_FINALLY L - <code for body> - POP_BLOCK - <code for finalbody> - JUMP E - L: - <code for finalbody> - E: - - The special instructions use the block stack. Each block - stack entry contains the instruction that created it (here - SETUP_FINALLY), the level of the value stack at the time the - block stack entry was created, and a label (here L). - - SETUP_FINALLY: - Pushes the current value stack level and the label - onto the block stack. - POP_BLOCK: - Pops en entry from the block stack. - - The block stack is unwound when an exception is raised: - when a SETUP_FINALLY entry is found, the raised and the caught - exceptions are pushed onto the value stack (and the exception - condition is cleared), and the interpreter jumps to the label - gotten from the block stack. -*/ - -static int -compiler_try_finally(struct compiler *c, stmt_ty s) -{ - basicblock *body, *end, *exit; - - body = compiler_new_block(c); - end = compiler_new_block(c); - exit = compiler_new_block(c); - if (body == NULL || end == NULL || exit == NULL) - return 0; - - /* `try` block */ - ADDOP_JUMP(c, SETUP_FINALLY, end); - compiler_use_next_block(c, body); - if (!compiler_push_fblock(c, FINALLY_TRY, body, end, s->v.Try.finalbody)) - return 0; - if (s->v.Try.handlers && asdl_seq_LEN(s->v.Try.handlers)) { - if (!compiler_try_except(c, s)) - return 0; - } - else { - VISIT_SEQ(c, stmt, s->v.Try.body); - } - ADDOP_NOLINE(c, POP_BLOCK); - compiler_pop_fblock(c, FINALLY_TRY, body); - VISIT_SEQ(c, stmt, s->v.Try.finalbody); - ADDOP_JUMP_NOLINE(c, JUMP_FORWARD, exit); - /* `finally` block */ - compiler_use_next_block(c, end); - if (!compiler_push_fblock(c, FINALLY_END, end, NULL, NULL)) - return 0; - VISIT_SEQ(c, stmt, s->v.Try.finalbody); - compiler_pop_fblock(c, FINALLY_END, end); - ADDOP_I(c, RERAISE, 0); - compiler_use_next_block(c, exit); - return 1; -} - -/* - Code generated for "try: S except E1 as V1: S1 except E2 as V2: S2 ...": - (The contents of the value stack is shown in [], with the top - at the right; 'tb' is trace-back info, 'val' the exception's - associated value, and 'exc' the exception.) - - Value stack Label Instruction Argument - [] SETUP_FINALLY L1 - [] <code for S> - [] POP_BLOCK - [] JUMP_FORWARD L0 - - [tb, val, exc] L1: DUP ) - [tb, val, exc, exc] <evaluate E1> ) - [tb, val, exc, exc, E1] JUMP_IF_NOT_EXC_MATCH L2 ) only if E1 - [tb, val, exc] POP - [tb, val] <assign to V1> (or POP if no V1) - [tb] POP - [] <code for S1> - JUMP_FORWARD L0 - - [tb, val, exc] L2: DUP - .............................etc....................... - - [tb, val, exc] Ln+1: RERAISE # re-raise exception - - [] L0: <next statement> - - Of course, parts are not generated if Vi or Ei is not present. -*/ -static int -compiler_try_except(struct compiler *c, stmt_ty s) -{ - basicblock *body, *orelse, *except, *end; - Py_ssize_t i, n; - - body = compiler_new_block(c); - except = compiler_new_block(c); - orelse = compiler_new_block(c); - end = compiler_new_block(c); - if (body == NULL || except == NULL || orelse == NULL || end == NULL) - return 0; - ADDOP_JUMP(c, SETUP_FINALLY, except); - compiler_use_next_block(c, body); - if (!compiler_push_fblock(c, TRY_EXCEPT, body, NULL, NULL)) - return 0; - VISIT_SEQ(c, stmt, s->v.Try.body); - compiler_pop_fblock(c, TRY_EXCEPT, body); - ADDOP_NOLINE(c, POP_BLOCK); - ADDOP_JUMP_NOLINE(c, JUMP_FORWARD, orelse); - n = asdl_seq_LEN(s->v.Try.handlers); - compiler_use_next_block(c, except); - /* Runtime will push a block here, so we need to account for that */ - if (!compiler_push_fblock(c, EXCEPTION_HANDLER, NULL, NULL, NULL)) - return 0; - for (i = 0; i < n; i++) { - excepthandler_ty handler = (excepthandler_ty)asdl_seq_GET( - s->v.Try.handlers, i); - SET_LOC(c, handler); - if (!handler->v.ExceptHandler.type && i < n-1) - return compiler_error(c, "default 'except:' must be last"); - except = compiler_new_block(c); - if (except == NULL) - return 0; - if (handler->v.ExceptHandler.type) { - ADDOP(c, DUP_TOP); - VISIT(c, expr, handler->v.ExceptHandler.type); - ADDOP_JUMP(c, JUMP_IF_NOT_EXC_MATCH, except); - NEXT_BLOCK(c); - } - ADDOP(c, POP_TOP); - if (handler->v.ExceptHandler.name) { - basicblock *cleanup_end, *cleanup_body; - - cleanup_end = compiler_new_block(c); - cleanup_body = compiler_new_block(c); - if (cleanup_end == NULL || cleanup_body == NULL) { - return 0; - } - - compiler_nameop(c, handler->v.ExceptHandler.name, Store); - ADDOP(c, POP_TOP); - - /* - try: - # body - except type as name: - try: - # body - finally: - name = None # in case body contains "del name" - del name - */ - - /* second try: */ - ADDOP_JUMP(c, SETUP_FINALLY, cleanup_end); - compiler_use_next_block(c, cleanup_body); - if (!compiler_push_fblock(c, HANDLER_CLEANUP, cleanup_body, NULL, handler->v.ExceptHandler.name)) - return 0; - - /* second # body */ - VISIT_SEQ(c, stmt, handler->v.ExceptHandler.body); - compiler_pop_fblock(c, HANDLER_CLEANUP, cleanup_body); - /* name = None; del name; # Mark as artificial */ - c->u->u_lineno = -1; - ADDOP(c, POP_BLOCK); - ADDOP(c, POP_EXCEPT); - ADDOP_LOAD_CONST(c, Py_None); - compiler_nameop(c, handler->v.ExceptHandler.name, Store); - compiler_nameop(c, handler->v.ExceptHandler.name, Del); - ADDOP_JUMP(c, JUMP_FORWARD, end); - - /* except: */ - compiler_use_next_block(c, cleanup_end); - - /* name = None; del name; # Mark as artificial */ - c->u->u_lineno = -1; - ADDOP_LOAD_CONST(c, Py_None); - compiler_nameop(c, handler->v.ExceptHandler.name, Store); - compiler_nameop(c, handler->v.ExceptHandler.name, Del); - - ADDOP_I(c, RERAISE, 1); - } - else { - basicblock *cleanup_body; - - cleanup_body = compiler_new_block(c); - if (!cleanup_body) - return 0; - - ADDOP(c, POP_TOP); - ADDOP(c, POP_TOP); - compiler_use_next_block(c, cleanup_body); - if (!compiler_push_fblock(c, HANDLER_CLEANUP, cleanup_body, NULL, NULL)) - return 0; - VISIT_SEQ(c, stmt, handler->v.ExceptHandler.body); - compiler_pop_fblock(c, HANDLER_CLEANUP, cleanup_body); - c->u->u_lineno = -1; - ADDOP(c, POP_EXCEPT); - ADDOP_JUMP(c, JUMP_FORWARD, end); - } - compiler_use_next_block(c, except); - } - compiler_pop_fblock(c, EXCEPTION_HANDLER, NULL); - /* Mark as artificial */ - c->u->u_lineno = -1; - ADDOP_I(c, RERAISE, 0); - compiler_use_next_block(c, orelse); - VISIT_SEQ(c, stmt, s->v.Try.orelse); - compiler_use_next_block(c, end); - return 1; -} - -static int -compiler_try(struct compiler *c, stmt_ty s) { - if (s->v.Try.finalbody && asdl_seq_LEN(s->v.Try.finalbody)) - return compiler_try_finally(c, s); - else - return compiler_try_except(c, s); -} - - -static int -compiler_import_as(struct compiler *c, identifier name, identifier asname) -{ - /* The IMPORT_NAME opcode was already generated. This function - merely needs to bind the result to a name. - - If there is a dot in name, we need to split it and emit a - IMPORT_FROM for each name. - */ - Py_ssize_t len = PyUnicode_GET_LENGTH(name); - Py_ssize_t dot = PyUnicode_FindChar(name, '.', 0, len, 1); - if (dot == -2) - return 0; - if (dot != -1) { - /* Consume the base module name to get the first attribute */ - while (1) { - Py_ssize_t pos = dot + 1; - PyObject *attr; - dot = PyUnicode_FindChar(name, '.', pos, len, 1); - if (dot == -2) - return 0; - attr = PyUnicode_Substring(name, pos, (dot != -1) ? dot : len); - if (!attr) - return 0; - ADDOP_N(c, IMPORT_FROM, attr, names); - if (dot == -1) { - break; - } - ADDOP(c, ROT_TWO); - ADDOP(c, POP_TOP); - } - if (!compiler_nameop(c, asname, Store)) { - return 0; - } - ADDOP(c, POP_TOP); - return 1; - } - return compiler_nameop(c, asname, Store); -} - -static int -compiler_import(struct compiler *c, stmt_ty s) -{ - /* The Import node stores a module name like a.b.c as a single - string. This is convenient for all cases except - import a.b.c as d - where we need to parse that string to extract the individual - module names. - XXX Perhaps change the representation to make this case simpler? - */ - Py_ssize_t i, n = asdl_seq_LEN(s->v.Import.names); - - PyObject *zero = _PyLong_GetZero(); // borrowed reference - for (i = 0; i < n; i++) { - alias_ty alias = (alias_ty)asdl_seq_GET(s->v.Import.names, i); - int r; - - ADDOP_LOAD_CONST(c, zero); - ADDOP_LOAD_CONST(c, Py_None); - ADDOP_NAME(c, IMPORT_NAME, alias->name, names); - - if (alias->asname) { - r = compiler_import_as(c, alias->name, alias->asname); - if (!r) - return r; - } - else { - identifier tmp = alias->name; - Py_ssize_t dot = PyUnicode_FindChar( - alias->name, '.', 0, PyUnicode_GET_LENGTH(alias->name), 1); - if (dot != -1) { - tmp = PyUnicode_Substring(alias->name, 0, dot); - if (tmp == NULL) - return 0; - } - r = compiler_nameop(c, tmp, Store); - if (dot != -1) { - Py_DECREF(tmp); - } - if (!r) - return r; - } - } - return 1; -} - -static int -compiler_from_import(struct compiler *c, stmt_ty s) -{ - Py_ssize_t i, n = asdl_seq_LEN(s->v.ImportFrom.names); - PyObject *names; - static PyObject *empty_string; - - if (!empty_string) { - empty_string = PyUnicode_FromString(""); - if (!empty_string) - return 0; - } - - ADDOP_LOAD_CONST_NEW(c, PyLong_FromLong(s->v.ImportFrom.level)); - - names = PyTuple_New(n); - if (!names) - return 0; - - /* build up the names */ - for (i = 0; i < n; i++) { - alias_ty alias = (alias_ty)asdl_seq_GET(s->v.ImportFrom.names, i); - Py_INCREF(alias->name); - PyTuple_SET_ITEM(names, i, alias->name); - } - - if (s->lineno > c->c_future->ff_lineno && s->v.ImportFrom.module && - _PyUnicode_EqualToASCIIString(s->v.ImportFrom.module, "__future__")) { - Py_DECREF(names); - return compiler_error(c, "from __future__ imports must occur " - "at the beginning of the file"); - } - ADDOP_LOAD_CONST_NEW(c, names); - - if (s->v.ImportFrom.module) { - ADDOP_NAME(c, IMPORT_NAME, s->v.ImportFrom.module, names); - } - else { - ADDOP_NAME(c, IMPORT_NAME, empty_string, names); - } - for (i = 0; i < n; i++) { - alias_ty alias = (alias_ty)asdl_seq_GET(s->v.ImportFrom.names, i); - identifier store_name; - - if (i == 0 && PyUnicode_READ_CHAR(alias->name, 0) == '*') { - assert(n == 1); - ADDOP(c, IMPORT_STAR); - return 1; - } - - ADDOP_NAME(c, IMPORT_FROM, alias->name, names); - store_name = alias->name; - if (alias->asname) - store_name = alias->asname; - - if (!compiler_nameop(c, store_name, Store)) { - return 0; - } - } - /* remove imported module */ - ADDOP(c, POP_TOP); - return 1; -} - -static int -compiler_assert(struct compiler *c, stmt_ty s) -{ - basicblock *end; - - /* Always emit a warning if the test is a non-zero length tuple */ - if ((s->v.Assert.test->kind == Tuple_kind && - asdl_seq_LEN(s->v.Assert.test->v.Tuple.elts) > 0) || - (s->v.Assert.test->kind == Constant_kind && - PyTuple_Check(s->v.Assert.test->v.Constant.value) && - PyTuple_Size(s->v.Assert.test->v.Constant.value) > 0)) - { - if (!compiler_warn(c, "assertion is always true, " - "perhaps remove parentheses?")) - { - return 0; - } - } - if (c->c_optimize) - return 1; - end = compiler_new_block(c); - if (end == NULL) - return 0; - if (!compiler_jump_if(c, s->v.Assert.test, end, 1)) - return 0; - ADDOP(c, LOAD_ASSERTION_ERROR); - if (s->v.Assert.msg) { - VISIT(c, expr, s->v.Assert.msg); - ADDOP_I(c, CALL_FUNCTION, 1); - } - ADDOP_I(c, RAISE_VARARGS, 1); - compiler_use_next_block(c, end); - return 1; -} - -static int -compiler_visit_stmt_expr(struct compiler *c, expr_ty value) -{ - if (c->c_interactive && c->c_nestlevel <= 1) { - VISIT(c, expr, value); - ADDOP(c, PRINT_EXPR); - return 1; - } - - if (value->kind == Constant_kind) { - /* ignore constant statement */ - ADDOP(c, NOP); - return 1; - } - - VISIT(c, expr, value); - /* Mark POP_TOP as artificial */ - c->u->u_lineno = -1; - ADDOP(c, POP_TOP); - return 1; -} - -static int -compiler_visit_stmt(struct compiler *c, stmt_ty s) -{ - Py_ssize_t i, n; - - /* Always assign a lineno to the next instruction for a stmt. */ - SET_LOC(c, s); - - switch (s->kind) { - case FunctionDef_kind: - return compiler_function(c, s, 0); - case ClassDef_kind: - return compiler_class(c, s); - case Return_kind: - return compiler_return(c, s); - case Delete_kind: - VISIT_SEQ(c, expr, s->v.Delete.targets) - break; - case Assign_kind: - n = asdl_seq_LEN(s->v.Assign.targets); - VISIT(c, expr, s->v.Assign.value); - for (i = 0; i < n; i++) { - if (i < n - 1) - ADDOP(c, DUP_TOP); - VISIT(c, expr, - (expr_ty)asdl_seq_GET(s->v.Assign.targets, i)); - } - break; - case AugAssign_kind: - return compiler_augassign(c, s); - case AnnAssign_kind: - return compiler_annassign(c, s); - case For_kind: - return compiler_for(c, s); - case While_kind: - return compiler_while(c, s); - case If_kind: - return compiler_if(c, s); - case Match_kind: - return compiler_match(c, s); - case Raise_kind: - n = 0; - if (s->v.Raise.exc) { - VISIT(c, expr, s->v.Raise.exc); - n++; - if (s->v.Raise.cause) { - VISIT(c, expr, s->v.Raise.cause); - n++; - } - } - ADDOP_I(c, RAISE_VARARGS, (int)n); - NEXT_BLOCK(c); - break; - case Try_kind: - return compiler_try(c, s); - case Assert_kind: - return compiler_assert(c, s); - case Import_kind: - return compiler_import(c, s); - case ImportFrom_kind: - return compiler_from_import(c, s); - case Global_kind: - case Nonlocal_kind: - break; - case Expr_kind: - return compiler_visit_stmt_expr(c, s->v.Expr.value); - case Pass_kind: - ADDOP(c, NOP); - break; - case Break_kind: - return compiler_break(c); - case Continue_kind: - return compiler_continue(c); - case With_kind: - return compiler_with(c, s, 0); - case AsyncFunctionDef_kind: - return compiler_function(c, s, 1); - case AsyncWith_kind: - return compiler_async_with(c, s, 0); - case AsyncFor_kind: - return compiler_async_for(c, s); - } - - return 1; -} - -static int -unaryop(unaryop_ty op) -{ - switch (op) { - case Invert: - return UNARY_INVERT; - case Not: - return UNARY_NOT; - case UAdd: - return UNARY_POSITIVE; - case USub: - return UNARY_NEGATIVE; - default: - PyErr_Format(PyExc_SystemError, - "unary op %d should not be possible", op); - return 0; - } -} - -static int -binop(operator_ty op) -{ - switch (op) { - case Add: - return BINARY_ADD; - case Sub: - return BINARY_SUBTRACT; - case Mult: - return BINARY_MULTIPLY; - case MatMult: - return BINARY_MATRIX_MULTIPLY; - case Div: - return BINARY_TRUE_DIVIDE; - case Mod: - return BINARY_MODULO; - case Pow: - return BINARY_POWER; - case LShift: - return BINARY_LSHIFT; - case RShift: - return BINARY_RSHIFT; - case BitOr: - return BINARY_OR; - case BitXor: - return BINARY_XOR; - case BitAnd: - return BINARY_AND; - case FloorDiv: - return BINARY_FLOOR_DIVIDE; - default: - PyErr_Format(PyExc_SystemError, - "binary op %d should not be possible", op); - return 0; - } -} - -static int -inplace_binop(operator_ty op) -{ - switch (op) { - case Add: - return INPLACE_ADD; - case Sub: - return INPLACE_SUBTRACT; - case Mult: - return INPLACE_MULTIPLY; - case MatMult: - return INPLACE_MATRIX_MULTIPLY; - case Div: - return INPLACE_TRUE_DIVIDE; - case Mod: - return INPLACE_MODULO; - case Pow: - return INPLACE_POWER; - case LShift: - return INPLACE_LSHIFT; - case RShift: - return INPLACE_RSHIFT; - case BitOr: - return INPLACE_OR; - case BitXor: - return INPLACE_XOR; - case BitAnd: - return INPLACE_AND; - case FloorDiv: - return INPLACE_FLOOR_DIVIDE; - default: - PyErr_Format(PyExc_SystemError, - "inplace binary op %d should not be possible", op); - return 0; - } -} - -static int -compiler_nameop(struct compiler *c, identifier name, expr_context_ty ctx) -{ - int op, scope; - Py_ssize_t arg; - enum { OP_FAST, OP_GLOBAL, OP_DEREF, OP_NAME } optype; - - PyObject *dict = c->u->u_names; - PyObject *mangled; - - assert(!_PyUnicode_EqualToASCIIString(name, "None") && - !_PyUnicode_EqualToASCIIString(name, "True") && - !_PyUnicode_EqualToASCIIString(name, "False")); - - if (forbidden_name(c, name, ctx)) - return 0; - - mangled = _Py_Mangle(c->u->u_private, name); - if (!mangled) - return 0; - - op = 0; - optype = OP_NAME; - scope = _PyST_GetScope(c->u->u_ste, mangled); - switch (scope) { - case FREE: - dict = c->u->u_freevars; - optype = OP_DEREF; - break; - case CELL: - dict = c->u->u_cellvars; - optype = OP_DEREF; - break; - case LOCAL: - if (c->u->u_ste->ste_type == FunctionBlock) - optype = OP_FAST; - break; - case GLOBAL_IMPLICIT: - if (c->u->u_ste->ste_type == FunctionBlock) - optype = OP_GLOBAL; - break; - case GLOBAL_EXPLICIT: - optype = OP_GLOBAL; - break; - default: - /* scope can be 0 */ - break; - } - - /* XXX Leave assert here, but handle __doc__ and the like better */ - assert(scope || PyUnicode_READ_CHAR(name, 0) == '_'); - - switch (optype) { - case OP_DEREF: - switch (ctx) { - case Load: - op = (c->u->u_ste->ste_type == ClassBlock) ? LOAD_CLASSDEREF : LOAD_DEREF; - break; - case Store: op = STORE_DEREF; break; - case Del: op = DELETE_DEREF; break; - } - break; - case OP_FAST: - switch (ctx) { - case Load: op = LOAD_FAST; break; - case Store: op = STORE_FAST; break; - case Del: op = DELETE_FAST; break; - } - ADDOP_N(c, op, mangled, varnames); - return 1; - case OP_GLOBAL: - switch (ctx) { - case Load: op = LOAD_GLOBAL; break; - case Store: op = STORE_GLOBAL; break; - case Del: op = DELETE_GLOBAL; break; - } - break; - case OP_NAME: - switch (ctx) { - case Load: op = LOAD_NAME; break; - case Store: op = STORE_NAME; break; - case Del: op = DELETE_NAME; break; - } - break; - } - - assert(op); - arg = compiler_add_o(dict, mangled); - Py_DECREF(mangled); - if (arg < 0) - return 0; - return compiler_addop_i(c, op, arg); -} - -static int -compiler_boolop(struct compiler *c, expr_ty e) -{ - basicblock *end; - int jumpi; - Py_ssize_t i, n; - asdl_expr_seq *s; - - assert(e->kind == BoolOp_kind); - if (e->v.BoolOp.op == And) - jumpi = JUMP_IF_FALSE_OR_POP; - else - jumpi = JUMP_IF_TRUE_OR_POP; - end = compiler_new_block(c); - if (end == NULL) - return 0; - s = e->v.BoolOp.values; - n = asdl_seq_LEN(s) - 1; - assert(n >= 0); - for (i = 0; i < n; ++i) { - VISIT(c, expr, (expr_ty)asdl_seq_GET(s, i)); - ADDOP_JUMP(c, jumpi, end); - basicblock *next = compiler_new_block(c); - if (next == NULL) { - return 0; - } - compiler_use_next_block(c, next); - } - VISIT(c, expr, (expr_ty)asdl_seq_GET(s, n)); - compiler_use_next_block(c, end); - return 1; -} - -static int -starunpack_helper(struct compiler *c, asdl_expr_seq *elts, int pushed, - int build, int add, int extend, int tuple) -{ - Py_ssize_t n = asdl_seq_LEN(elts); - if (n > 2 && are_all_items_const(elts, 0, n)) { - PyObject *folded = PyTuple_New(n); - if (folded == NULL) { - return 0; - } - PyObject *val; - for (Py_ssize_t i = 0; i < n; i++) { - val = ((expr_ty)asdl_seq_GET(elts, i))->v.Constant.value; - Py_INCREF(val); - PyTuple_SET_ITEM(folded, i, val); - } - if (tuple) { - ADDOP_LOAD_CONST_NEW(c, folded); - } else { - if (add == SET_ADD) { - Py_SETREF(folded, PyFrozenSet_New(folded)); - if (folded == NULL) { - return 0; - } - } - ADDOP_I(c, build, pushed); - ADDOP_LOAD_CONST_NEW(c, folded); - ADDOP_I(c, extend, 1); - } - return 1; - } - - int big = n+pushed > STACK_USE_GUIDELINE; - int seen_star = 0; - for (Py_ssize_t i = 0; i < n; i++) { - expr_ty elt = asdl_seq_GET(elts, i); - if (elt->kind == Starred_kind) { - seen_star = 1; - } - } - if (!seen_star && !big) { - for (Py_ssize_t i = 0; i < n; i++) { - expr_ty elt = asdl_seq_GET(elts, i); - VISIT(c, expr, elt); - } - if (tuple) { - ADDOP_I(c, BUILD_TUPLE, n+pushed); - } else { - ADDOP_I(c, build, n+pushed); - } - return 1; - } - int sequence_built = 0; - if (big) { - ADDOP_I(c, build, pushed); - sequence_built = 1; - } - for (Py_ssize_t i = 0; i < n; i++) { - expr_ty elt = asdl_seq_GET(elts, i); - if (elt->kind == Starred_kind) { - if (sequence_built == 0) { - ADDOP_I(c, build, i+pushed); - sequence_built = 1; - } - VISIT(c, expr, elt->v.Starred.value); - ADDOP_I(c, extend, 1); - } - else { - VISIT(c, expr, elt); - if (sequence_built) { - ADDOP_I(c, add, 1); - } - } - } - assert(sequence_built); - if (tuple) { - ADDOP(c, LIST_TO_TUPLE); - } - return 1; -} - -static int -unpack_helper(struct compiler *c, asdl_expr_seq *elts) -{ - Py_ssize_t n = asdl_seq_LEN(elts); - int seen_star = 0; - for (Py_ssize_t i = 0; i < n; i++) { - expr_ty elt = asdl_seq_GET(elts, i); - if (elt->kind == Starred_kind && !seen_star) { - if ((i >= (1 << 8)) || - (n-i-1 >= (INT_MAX >> 8))) - return compiler_error(c, - "too many expressions in " - "star-unpacking assignment"); - ADDOP_I(c, UNPACK_EX, (i + ((n-i-1) << 8))); - seen_star = 1; - } - else if (elt->kind == Starred_kind) { - return compiler_error(c, - "multiple starred expressions in assignment"); - } - } - if (!seen_star) { - ADDOP_I(c, UNPACK_SEQUENCE, n); - } - return 1; -} - -static int -assignment_helper(struct compiler *c, asdl_expr_seq *elts) -{ - Py_ssize_t n = asdl_seq_LEN(elts); - RETURN_IF_FALSE(unpack_helper(c, elts)); - for (Py_ssize_t i = 0; i < n; i++) { - expr_ty elt = asdl_seq_GET(elts, i); - VISIT(c, expr, elt->kind != Starred_kind ? elt : elt->v.Starred.value); - } - return 1; -} - -static int -compiler_list(struct compiler *c, expr_ty e) -{ - asdl_expr_seq *elts = e->v.List.elts; - if (e->v.List.ctx == Store) { - return assignment_helper(c, elts); - } - else if (e->v.List.ctx == Load) { - return starunpack_helper(c, elts, 0, BUILD_LIST, - LIST_APPEND, LIST_EXTEND, 0); - } - else - VISIT_SEQ(c, expr, elts); - return 1; -} - -static int -compiler_tuple(struct compiler *c, expr_ty e) -{ - asdl_expr_seq *elts = e->v.Tuple.elts; - if (e->v.Tuple.ctx == Store) { - return assignment_helper(c, elts); - } - else if (e->v.Tuple.ctx == Load) { - return starunpack_helper(c, elts, 0, BUILD_LIST, - LIST_APPEND, LIST_EXTEND, 1); - } - else - VISIT_SEQ(c, expr, elts); - return 1; -} - -static int -compiler_set(struct compiler *c, expr_ty e) -{ - return starunpack_helper(c, e->v.Set.elts, 0, BUILD_SET, - SET_ADD, SET_UPDATE, 0); -} - -static int -are_all_items_const(asdl_expr_seq *seq, Py_ssize_t begin, Py_ssize_t end) -{ - Py_ssize_t i; - for (i = begin; i < end; i++) { - expr_ty key = (expr_ty)asdl_seq_GET(seq, i); - if (key == NULL || key->kind != Constant_kind) - return 0; - } - return 1; -} - -static int -compiler_subdict(struct compiler *c, expr_ty e, Py_ssize_t begin, Py_ssize_t end) -{ - Py_ssize_t i, n = end - begin; - PyObject *keys, *key; - int big = n*2 > STACK_USE_GUIDELINE; - if (n > 1 && !big && are_all_items_const(e->v.Dict.keys, begin, end)) { - for (i = begin; i < end; i++) { - VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Dict.values, i)); - } - keys = PyTuple_New(n); - if (keys == NULL) { - return 0; - } - for (i = begin; i < end; i++) { - key = ((expr_ty)asdl_seq_GET(e->v.Dict.keys, i))->v.Constant.value; - Py_INCREF(key); - PyTuple_SET_ITEM(keys, i - begin, key); - } - ADDOP_LOAD_CONST_NEW(c, keys); - ADDOP_I(c, BUILD_CONST_KEY_MAP, n); - return 1; - } - if (big) { - ADDOP_I(c, BUILD_MAP, 0); - } - for (i = begin; i < end; i++) { - VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Dict.keys, i)); - VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Dict.values, i)); - if (big) { - ADDOP_I(c, MAP_ADD, 1); - } - } - if (!big) { - ADDOP_I(c, BUILD_MAP, n); - } - return 1; -} - -static int -compiler_dict(struct compiler *c, expr_ty e) -{ - Py_ssize_t i, n, elements; - int have_dict; - int is_unpacking = 0; - n = asdl_seq_LEN(e->v.Dict.values); - have_dict = 0; - elements = 0; - for (i = 0; i < n; i++) { - is_unpacking = (expr_ty)asdl_seq_GET(e->v.Dict.keys, i) == NULL; - if (is_unpacking) { - if (elements) { - if (!compiler_subdict(c, e, i - elements, i)) { - return 0; - } - if (have_dict) { - ADDOP_I(c, DICT_UPDATE, 1); - } - have_dict = 1; - elements = 0; - } - if (have_dict == 0) { - ADDOP_I(c, BUILD_MAP, 0); - have_dict = 1; - } - VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Dict.values, i)); - ADDOP_I(c, DICT_UPDATE, 1); - } - else { - if (elements*2 > STACK_USE_GUIDELINE) { - if (!compiler_subdict(c, e, i - elements, i + 1)) { - return 0; - } - if (have_dict) { - ADDOP_I(c, DICT_UPDATE, 1); - } - have_dict = 1; - elements = 0; - } - else { - elements++; - } - } - } - if (elements) { - if (!compiler_subdict(c, e, n - elements, n)) { - return 0; - } - if (have_dict) { - ADDOP_I(c, DICT_UPDATE, 1); - } - have_dict = 1; - } - if (!have_dict) { - ADDOP_I(c, BUILD_MAP, 0); - } - return 1; -} - -static int -compiler_compare(struct compiler *c, expr_ty e) -{ - Py_ssize_t i, n; - - if (!check_compare(c, e)) { - return 0; - } - VISIT(c, expr, e->v.Compare.left); - assert(asdl_seq_LEN(e->v.Compare.ops) > 0); - n = asdl_seq_LEN(e->v.Compare.ops) - 1; - if (n == 0) { - VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Compare.comparators, 0)); - ADDOP_COMPARE(c, asdl_seq_GET(e->v.Compare.ops, 0)); - } - else { - basicblock *cleanup = compiler_new_block(c); - if (cleanup == NULL) - return 0; - for (i = 0; i < n; i++) { - VISIT(c, expr, - (expr_ty)asdl_seq_GET(e->v.Compare.comparators, i)); - ADDOP(c, DUP_TOP); - ADDOP(c, ROT_THREE); - ADDOP_COMPARE(c, asdl_seq_GET(e->v.Compare.ops, i)); - ADDOP_JUMP(c, JUMP_IF_FALSE_OR_POP, cleanup); - NEXT_BLOCK(c); - } - VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Compare.comparators, n)); - ADDOP_COMPARE(c, asdl_seq_GET(e->v.Compare.ops, n)); - basicblock *end = compiler_new_block(c); - if (end == NULL) - return 0; - ADDOP_JUMP_NOLINE(c, JUMP_FORWARD, end); - compiler_use_next_block(c, cleanup); - ADDOP(c, ROT_TWO); - ADDOP(c, POP_TOP); - compiler_use_next_block(c, end); - } - return 1; -} - -static PyTypeObject * -infer_type(expr_ty e) -{ - switch (e->kind) { - case Tuple_kind: - return &PyTuple_Type; - case List_kind: - case ListComp_kind: - return &PyList_Type; - case Dict_kind: - case DictComp_kind: - return &PyDict_Type; - case Set_kind: - case SetComp_kind: - return &PySet_Type; - case GeneratorExp_kind: - return &PyGen_Type; - case Lambda_kind: - return &PyFunction_Type; - case JoinedStr_kind: - case FormattedValue_kind: - return &PyUnicode_Type; - case Constant_kind: - return Py_TYPE(e->v.Constant.value); - default: - return NULL; - } -} - -static int -check_caller(struct compiler *c, expr_ty e) -{ - switch (e->kind) { - case Constant_kind: - case Tuple_kind: - case List_kind: - case ListComp_kind: - case Dict_kind: - case DictComp_kind: - case Set_kind: - case SetComp_kind: - case GeneratorExp_kind: - case JoinedStr_kind: - case FormattedValue_kind: - return compiler_warn(c, "'%.200s' object is not callable; " - "perhaps you missed a comma?", - infer_type(e)->tp_name); - default: - return 1; - } -} - -static int -check_subscripter(struct compiler *c, expr_ty e) -{ - PyObject *v; - - switch (e->kind) { - case Constant_kind: - v = e->v.Constant.value; - if (!(v == Py_None || v == Py_Ellipsis || - PyLong_Check(v) || PyFloat_Check(v) || PyComplex_Check(v) || - PyAnySet_Check(v))) - { - return 1; - } - /* fall through */ - case Set_kind: - case SetComp_kind: - case GeneratorExp_kind: - case Lambda_kind: - return compiler_warn(c, "'%.200s' object is not subscriptable; " - "perhaps you missed a comma?", - infer_type(e)->tp_name); - default: - return 1; - } -} - -static int -check_index(struct compiler *c, expr_ty e, expr_ty s) -{ - PyObject *v; - - PyTypeObject *index_type = infer_type(s); - if (index_type == NULL - || PyType_FastSubclass(index_type, Py_TPFLAGS_LONG_SUBCLASS) - || index_type == &PySlice_Type) { - return 1; - } - - switch (e->kind) { - case Constant_kind: - v = e->v.Constant.value; - if (!(PyUnicode_Check(v) || PyBytes_Check(v) || PyTuple_Check(v))) { - return 1; - } - /* fall through */ - case Tuple_kind: - case List_kind: - case ListComp_kind: - case JoinedStr_kind: - case FormattedValue_kind: - return compiler_warn(c, "%.200s indices must be integers or slices, " - "not %.200s; " - "perhaps you missed a comma?", - infer_type(e)->tp_name, - index_type->tp_name); - default: - return 1; - } -} - -// Return 1 if the method call was optimized, -1 if not, and 0 on error. -static int -maybe_optimize_method_call(struct compiler *c, expr_ty e) -{ - Py_ssize_t argsl, i; - expr_ty meth = e->v.Call.func; - asdl_expr_seq *args = e->v.Call.args; - - /* Check that the call node is an attribute access, and that - the call doesn't have keyword parameters. */ - if (meth->kind != Attribute_kind || meth->v.Attribute.ctx != Load || - asdl_seq_LEN(e->v.Call.keywords)) { - return -1; - } - /* Check that there aren't too many arguments */ - argsl = asdl_seq_LEN(args); - if (argsl >= STACK_USE_GUIDELINE) { - return -1; - } - /* Check that there are no *varargs types of arguments. */ - for (i = 0; i < argsl; i++) { - expr_ty elt = asdl_seq_GET(args, i); - if (elt->kind == Starred_kind) { - return -1; - } - } - - /* Alright, we can optimize the code. */ - VISIT(c, expr, meth->v.Attribute.value); - int old_lineno = c->u->u_lineno; - c->u->u_lineno = meth->end_lineno; - ADDOP_NAME(c, LOAD_METHOD, meth->v.Attribute.attr, names); - VISIT_SEQ(c, expr, e->v.Call.args); - ADDOP_I(c, CALL_METHOD, asdl_seq_LEN(e->v.Call.args)); - c->u->u_lineno = old_lineno; - return 1; -} - -static int -validate_keywords(struct compiler *c, asdl_keyword_seq *keywords) -{ - Py_ssize_t nkeywords = asdl_seq_LEN(keywords); - for (Py_ssize_t i = 0; i < nkeywords; i++) { - keyword_ty key = ((keyword_ty)asdl_seq_GET(keywords, i)); - if (key->arg == NULL) { - continue; - } - if (forbidden_name(c, key->arg, Store)) { - return -1; - } - for (Py_ssize_t j = i + 1; j < nkeywords; j++) { - keyword_ty other = ((keyword_ty)asdl_seq_GET(keywords, j)); - if (other->arg && !PyUnicode_Compare(key->arg, other->arg)) { - SET_LOC(c, other); - compiler_error(c, "keyword argument repeated: %U", key->arg); - return -1; - } - } - } - return 0; -} - -static int -compiler_call(struct compiler *c, expr_ty e) -{ - int ret = maybe_optimize_method_call(c, e); - if (ret >= 0) { - return ret; - } - if (!check_caller(c, e->v.Call.func)) { - return 0; - } - VISIT(c, expr, e->v.Call.func); - return compiler_call_helper(c, 0, - e->v.Call.args, - e->v.Call.keywords); -} - -static int -compiler_joined_str(struct compiler *c, expr_ty e) -{ - - Py_ssize_t value_count = asdl_seq_LEN(e->v.JoinedStr.values); - if (value_count > STACK_USE_GUIDELINE) { - ADDOP_LOAD_CONST_NEW(c, _PyUnicode_FromASCII("", 0)); - PyObject *join = _PyUnicode_FromASCII("join", 4); - if (join == NULL) { - return 0; - } - ADDOP_NAME(c, LOAD_METHOD, join, names); - Py_DECREF(join); - ADDOP_I(c, BUILD_LIST, 0); - for (Py_ssize_t i = 0; i < asdl_seq_LEN(e->v.JoinedStr.values); i++) { - VISIT(c, expr, asdl_seq_GET(e->v.JoinedStr.values, i)); - ADDOP_I(c, LIST_APPEND, 1); - } - ADDOP_I(c, CALL_METHOD, 1); - } - else { - VISIT_SEQ(c, expr, e->v.JoinedStr.values); - if (asdl_seq_LEN(e->v.JoinedStr.values) != 1) { - ADDOP_I(c, BUILD_STRING, asdl_seq_LEN(e->v.JoinedStr.values)); - } - } - return 1; -} - -/* Used to implement f-strings. Format a single value. */ -static int -compiler_formatted_value(struct compiler *c, expr_ty e) -{ - /* Our oparg encodes 2 pieces of information: the conversion - character, and whether or not a format_spec was provided. - - Convert the conversion char to 3 bits: - : 000 0x0 FVC_NONE The default if nothing specified. - !s : 001 0x1 FVC_STR - !r : 010 0x2 FVC_REPR - !a : 011 0x3 FVC_ASCII - - next bit is whether or not we have a format spec: - yes : 100 0x4 - no : 000 0x0 - */ - - int conversion = e->v.FormattedValue.conversion; - int oparg; - - /* The expression to be formatted. */ - VISIT(c, expr, e->v.FormattedValue.value); - - switch (conversion) { - case 's': oparg = FVC_STR; break; - case 'r': oparg = FVC_REPR; break; - case 'a': oparg = FVC_ASCII; break; - case -1: oparg = FVC_NONE; break; - default: - PyErr_Format(PyExc_SystemError, - "Unrecognized conversion character %d", conversion); - return 0; - } - if (e->v.FormattedValue.format_spec) { - /* Evaluate the format spec, and update our opcode arg. */ - VISIT(c, expr, e->v.FormattedValue.format_spec); - oparg |= FVS_HAVE_SPEC; - } - - /* And push our opcode and oparg */ - ADDOP_I(c, FORMAT_VALUE, oparg); - - return 1; -} - -static int -compiler_subkwargs(struct compiler *c, asdl_keyword_seq *keywords, Py_ssize_t begin, Py_ssize_t end) -{ - Py_ssize_t i, n = end - begin; - keyword_ty kw; - PyObject *keys, *key; - assert(n > 0); - int big = n*2 > STACK_USE_GUIDELINE; - if (n > 1 && !big) { - for (i = begin; i < end; i++) { - kw = asdl_seq_GET(keywords, i); - VISIT(c, expr, kw->value); - } - keys = PyTuple_New(n); - if (keys == NULL) { - return 0; - } - for (i = begin; i < end; i++) { - key = ((keyword_ty) asdl_seq_GET(keywords, i))->arg; - Py_INCREF(key); - PyTuple_SET_ITEM(keys, i - begin, key); - } - ADDOP_LOAD_CONST_NEW(c, keys); - ADDOP_I(c, BUILD_CONST_KEY_MAP, n); - return 1; - } - if (big) { - ADDOP_I_NOLINE(c, BUILD_MAP, 0); - } - for (i = begin; i < end; i++) { - kw = asdl_seq_GET(keywords, i); - ADDOP_LOAD_CONST(c, kw->arg); - VISIT(c, expr, kw->value); - if (big) { - ADDOP_I_NOLINE(c, MAP_ADD, 1); - } - } - if (!big) { - ADDOP_I(c, BUILD_MAP, n); - } - return 1; -} - -/* shared code between compiler_call and compiler_class */ -static int -compiler_call_helper(struct compiler *c, - int n, /* Args already pushed */ - asdl_expr_seq *args, - asdl_keyword_seq *keywords) -{ - Py_ssize_t i, nseen, nelts, nkwelts; - - if (validate_keywords(c, keywords) == -1) { - return 0; - } - - nelts = asdl_seq_LEN(args); - nkwelts = asdl_seq_LEN(keywords); - - if (nelts + nkwelts*2 > STACK_USE_GUIDELINE) { - goto ex_call; - } - for (i = 0; i < nelts; i++) { - expr_ty elt = asdl_seq_GET(args, i); - if (elt->kind == Starred_kind) { - goto ex_call; - } - } - for (i = 0; i < nkwelts; i++) { - keyword_ty kw = asdl_seq_GET(keywords, i); - if (kw->arg == NULL) { - goto ex_call; - } - } - - /* No * or ** args, so can use faster calling sequence */ - for (i = 0; i < nelts; i++) { - expr_ty elt = asdl_seq_GET(args, i); - assert(elt->kind != Starred_kind); - VISIT(c, expr, elt); - } - if (nkwelts) { - PyObject *names; - VISIT_SEQ(c, keyword, keywords); - names = PyTuple_New(nkwelts); - if (names == NULL) { - return 0; - } - for (i = 0; i < nkwelts; i++) { - keyword_ty kw = asdl_seq_GET(keywords, i); - Py_INCREF(kw->arg); - PyTuple_SET_ITEM(names, i, kw->arg); - } - ADDOP_LOAD_CONST_NEW(c, names); - ADDOP_I(c, CALL_FUNCTION_KW, n + nelts + nkwelts); - return 1; - } - else { - ADDOP_I(c, CALL_FUNCTION, n + nelts); - return 1; - } - -ex_call: - - /* Do positional arguments. */ - if (n ==0 && nelts == 1 && ((expr_ty)asdl_seq_GET(args, 0))->kind == Starred_kind) { - VISIT(c, expr, ((expr_ty)asdl_seq_GET(args, 0))->v.Starred.value); - } - else if (starunpack_helper(c, args, n, BUILD_LIST, - LIST_APPEND, LIST_EXTEND, 1) == 0) { - return 0; - } - /* Then keyword arguments */ - if (nkwelts) { - /* Has a new dict been pushed */ - int have_dict = 0; - - nseen = 0; /* the number of keyword arguments on the stack following */ - for (i = 0; i < nkwelts; i++) { - keyword_ty kw = asdl_seq_GET(keywords, i); - if (kw->arg == NULL) { - /* A keyword argument unpacking. */ - if (nseen) { - if (!compiler_subkwargs(c, keywords, i - nseen, i)) { - return 0; - } - if (have_dict) { - ADDOP_I(c, DICT_MERGE, 1); - } - have_dict = 1; - nseen = 0; - } - if (!have_dict) { - ADDOP_I(c, BUILD_MAP, 0); - have_dict = 1; - } - VISIT(c, expr, kw->value); - ADDOP_I(c, DICT_MERGE, 1); - } - else { - nseen++; - } - } - if (nseen) { - /* Pack up any trailing keyword arguments. */ - if (!compiler_subkwargs(c, keywords, nkwelts - nseen, nkwelts)) { - return 0; - } - if (have_dict) { - ADDOP_I(c, DICT_MERGE, 1); - } - have_dict = 1; - } - assert(have_dict); - } - ADDOP_I(c, CALL_FUNCTION_EX, nkwelts > 0); - return 1; -} - - -/* List and set comprehensions and generator expressions work by creating a - nested function to perform the actual iteration. This means that the - iteration variables don't leak into the current scope. - The defined function is called immediately following its definition, with the - result of that call being the result of the expression. - The LC/SC version returns the populated container, while the GE version is - flagged in symtable.c as a generator, so it returns the generator object - when the function is called. - - Possible cleanups: - - iterate over the generator sequence instead of using recursion -*/ - - -static int -compiler_comprehension_generator(struct compiler *c, - asdl_comprehension_seq *generators, int gen_index, - int depth, - expr_ty elt, expr_ty val, int type) -{ - comprehension_ty gen; - gen = (comprehension_ty)asdl_seq_GET(generators, gen_index); - if (gen->is_async) { - return compiler_async_comprehension_generator( - c, generators, gen_index, depth, elt, val, type); - } else { - return compiler_sync_comprehension_generator( - c, generators, gen_index, depth, elt, val, type); - } -} - -static int -compiler_sync_comprehension_generator(struct compiler *c, - asdl_comprehension_seq *generators, int gen_index, - int depth, - expr_ty elt, expr_ty val, int type) -{ - /* generate code for the iterator, then each of the ifs, - and then write to the element */ - - comprehension_ty gen; - basicblock *start, *anchor, *skip, *if_cleanup; - Py_ssize_t i, n; - - start = compiler_new_block(c); - skip = compiler_new_block(c); - if_cleanup = compiler_new_block(c); - anchor = compiler_new_block(c); - - if (start == NULL || skip == NULL || if_cleanup == NULL || - anchor == NULL) - return 0; - - gen = (comprehension_ty)asdl_seq_GET(generators, gen_index); - - if (gen_index == 0) { - /* Receive outermost iter as an implicit argument */ - c->u->u_argcount = 1; - ADDOP_I(c, LOAD_FAST, 0); - } - else { - /* Sub-iter - calculate on the fly */ - /* Fast path for the temporary variable assignment idiom: - for y in [f(x)] - */ - asdl_expr_seq *elts; - switch (gen->iter->kind) { - case List_kind: - elts = gen->iter->v.List.elts; - break; - case Tuple_kind: - elts = gen->iter->v.Tuple.elts; - break; - default: - elts = NULL; - } - if (asdl_seq_LEN(elts) == 1) { - expr_ty elt = asdl_seq_GET(elts, 0); - if (elt->kind != Starred_kind) { - VISIT(c, expr, elt); - start = NULL; - } - } - if (start) { - VISIT(c, expr, gen->iter); - ADDOP(c, GET_ITER); - } - } - if (start) { - depth++; - compiler_use_next_block(c, start); - ADDOP_JUMP(c, FOR_ITER, anchor); - NEXT_BLOCK(c); - } - VISIT(c, expr, gen->target); - - /* XXX this needs to be cleaned up...a lot! */ - n = asdl_seq_LEN(gen->ifs); - for (i = 0; i < n; i++) { - expr_ty e = (expr_ty)asdl_seq_GET(gen->ifs, i); - if (!compiler_jump_if(c, e, if_cleanup, 0)) - return 0; - NEXT_BLOCK(c); - } - - if (++gen_index < asdl_seq_LEN(generators)) - if (!compiler_comprehension_generator(c, - generators, gen_index, depth, - elt, val, type)) - return 0; - - /* only append after the last for generator */ - if (gen_index >= asdl_seq_LEN(generators)) { - /* comprehension specific code */ - switch (type) { - case COMP_GENEXP: - VISIT(c, expr, elt); - ADDOP(c, YIELD_VALUE); - ADDOP(c, POP_TOP); - break; - case COMP_LISTCOMP: - VISIT(c, expr, elt); - ADDOP_I(c, LIST_APPEND, depth + 1); - break; - case COMP_SETCOMP: - VISIT(c, expr, elt); - ADDOP_I(c, SET_ADD, depth + 1); - break; - case COMP_DICTCOMP: - /* With '{k: v}', k is evaluated before v, so we do - the same. */ - VISIT(c, expr, elt); - VISIT(c, expr, val); - ADDOP_I(c, MAP_ADD, depth + 1); - break; - default: - return 0; - } - - compiler_use_next_block(c, skip); - } - compiler_use_next_block(c, if_cleanup); - if (start) { - ADDOP_JUMP(c, JUMP_ABSOLUTE, start); - compiler_use_next_block(c, anchor); - } - - return 1; -} - -static int -compiler_async_comprehension_generator(struct compiler *c, - asdl_comprehension_seq *generators, int gen_index, - int depth, - expr_ty elt, expr_ty val, int type) -{ - comprehension_ty gen; - basicblock *start, *if_cleanup, *except; - Py_ssize_t i, n; - start = compiler_new_block(c); - except = compiler_new_block(c); - if_cleanup = compiler_new_block(c); - - if (start == NULL || if_cleanup == NULL || except == NULL) { - return 0; - } - - gen = (comprehension_ty)asdl_seq_GET(generators, gen_index); - - if (gen_index == 0) { - /* Receive outermost iter as an implicit argument */ - c->u->u_argcount = 1; - ADDOP_I(c, LOAD_FAST, 0); - } - else { - /* Sub-iter - calculate on the fly */ - VISIT(c, expr, gen->iter); - ADDOP(c, GET_AITER); - } - - compiler_use_next_block(c, start); - /* Runtime will push a block here, so we need to account for that */ - if (!compiler_push_fblock(c, ASYNC_COMPREHENSION_GENERATOR, start, - NULL, NULL)) { - return 0; - } - - ADDOP_JUMP(c, SETUP_FINALLY, except); - ADDOP(c, GET_ANEXT); - ADDOP_LOAD_CONST(c, Py_None); - ADDOP(c, YIELD_FROM); - ADDOP(c, POP_BLOCK); - VISIT(c, expr, gen->target); - - n = asdl_seq_LEN(gen->ifs); - for (i = 0; i < n; i++) { - expr_ty e = (expr_ty)asdl_seq_GET(gen->ifs, i); - if (!compiler_jump_if(c, e, if_cleanup, 0)) - return 0; - NEXT_BLOCK(c); - } - - depth++; - if (++gen_index < asdl_seq_LEN(generators)) - if (!compiler_comprehension_generator(c, - generators, gen_index, depth, - elt, val, type)) - return 0; - - /* only append after the last for generator */ - if (gen_index >= asdl_seq_LEN(generators)) { - /* comprehension specific code */ - switch (type) { - case COMP_GENEXP: - VISIT(c, expr, elt); - ADDOP(c, YIELD_VALUE); - ADDOP(c, POP_TOP); - break; - case COMP_LISTCOMP: - VISIT(c, expr, elt); - ADDOP_I(c, LIST_APPEND, depth + 1); - break; - case COMP_SETCOMP: - VISIT(c, expr, elt); - ADDOP_I(c, SET_ADD, depth + 1); - break; - case COMP_DICTCOMP: - /* With '{k: v}', k is evaluated before v, so we do - the same. */ - VISIT(c, expr, elt); - VISIT(c, expr, val); - ADDOP_I(c, MAP_ADD, depth + 1); - break; - default: - return 0; - } - } - compiler_use_next_block(c, if_cleanup); - ADDOP_JUMP(c, JUMP_ABSOLUTE, start); - - compiler_pop_fblock(c, ASYNC_COMPREHENSION_GENERATOR, start); - - compiler_use_next_block(c, except); - ADDOP(c, END_ASYNC_FOR); - - return 1; -} - -static int -compiler_comprehension(struct compiler *c, expr_ty e, int type, - identifier name, asdl_comprehension_seq *generators, expr_ty elt, - expr_ty val) -{ - PyCodeObject *co = NULL; - comprehension_ty outermost; - PyObject *qualname = NULL; - int is_async_generator = 0; - int top_level_await = IS_TOP_LEVEL_AWAIT(c); - - - int is_async_function = c->u->u_ste->ste_coroutine; - - outermost = (comprehension_ty) asdl_seq_GET(generators, 0); - if (!compiler_enter_scope(c, name, COMPILER_SCOPE_COMPREHENSION, - (void *)e, e->lineno)) - { - goto error; - } - SET_LOC(c, e); - - is_async_generator = c->u->u_ste->ste_coroutine; - - if (is_async_generator && !is_async_function && type != COMP_GENEXP && !top_level_await) { - compiler_error(c, "asynchronous comprehension outside of " - "an asynchronous function"); - goto error_in_scope; - } - - if (type != COMP_GENEXP) { - int op; - switch (type) { - case COMP_LISTCOMP: - op = BUILD_LIST; - break; - case COMP_SETCOMP: - op = BUILD_SET; - break; - case COMP_DICTCOMP: - op = BUILD_MAP; - break; - default: - PyErr_Format(PyExc_SystemError, - "unknown comprehension type %d", type); - goto error_in_scope; - } - - ADDOP_I(c, op, 0); - } - - if (!compiler_comprehension_generator(c, generators, 0, 0, elt, - val, type)) - goto error_in_scope; - - if (type != COMP_GENEXP) { - ADDOP(c, RETURN_VALUE); - } - - co = assemble(c, 1); - qualname = c->u->u_qualname; - Py_INCREF(qualname); - compiler_exit_scope(c); - if (top_level_await && is_async_generator){ - c->u->u_ste->ste_coroutine = 1; - } - if (co == NULL) - goto error; - - if (!compiler_make_closure(c, co, 0, qualname)) { - goto error; - } - Py_DECREF(qualname); - Py_DECREF(co); - - VISIT(c, expr, outermost->iter); - - if (outermost->is_async) { - ADDOP(c, GET_AITER); - } else { - ADDOP(c, GET_ITER); - } - - ADDOP_I(c, CALL_FUNCTION, 1); - - if (is_async_generator && type != COMP_GENEXP) { - ADDOP(c, GET_AWAITABLE); - ADDOP_LOAD_CONST(c, Py_None); - ADDOP(c, YIELD_FROM); - } - - return 1; -error_in_scope: - compiler_exit_scope(c); -error: - Py_XDECREF(qualname); - Py_XDECREF(co); - return 0; -} - -static int -compiler_genexp(struct compiler *c, expr_ty e) -{ - static identifier name; - if (!name) { - name = PyUnicode_InternFromString("<genexpr>"); - if (!name) - return 0; - } - assert(e->kind == GeneratorExp_kind); - return compiler_comprehension(c, e, COMP_GENEXP, name, - e->v.GeneratorExp.generators, - e->v.GeneratorExp.elt, NULL); -} - -static int -compiler_listcomp(struct compiler *c, expr_ty e) -{ - static identifier name; - if (!name) { - name = PyUnicode_InternFromString("<listcomp>"); - if (!name) - return 0; - } - assert(e->kind == ListComp_kind); - return compiler_comprehension(c, e, COMP_LISTCOMP, name, - e->v.ListComp.generators, - e->v.ListComp.elt, NULL); -} - -static int -compiler_setcomp(struct compiler *c, expr_ty e) -{ - static identifier name; - if (!name) { - name = PyUnicode_InternFromString("<setcomp>"); - if (!name) - return 0; - } - assert(e->kind == SetComp_kind); - return compiler_comprehension(c, e, COMP_SETCOMP, name, - e->v.SetComp.generators, - e->v.SetComp.elt, NULL); -} - - -static int -compiler_dictcomp(struct compiler *c, expr_ty e) -{ - static identifier name; - if (!name) { - name = PyUnicode_InternFromString("<dictcomp>"); - if (!name) - return 0; - } - assert(e->kind == DictComp_kind); - return compiler_comprehension(c, e, COMP_DICTCOMP, name, - e->v.DictComp.generators, - e->v.DictComp.key, e->v.DictComp.value); -} - - -static int -compiler_visit_keyword(struct compiler *c, keyword_ty k) -{ - VISIT(c, expr, k->value); - return 1; -} - -/* Test whether expression is constant. For constants, report - whether they are true or false. - - Return values: 1 for true, 0 for false, -1 for non-constant. - */ - -static int -compiler_with_except_finish(struct compiler *c) { - basicblock *exit; - exit = compiler_new_block(c); - if (exit == NULL) - return 0; - ADDOP_JUMP(c, POP_JUMP_IF_TRUE, exit); - NEXT_BLOCK(c); - ADDOP_I(c, RERAISE, 1); - compiler_use_next_block(c, exit); - ADDOP(c, POP_TOP); - ADDOP(c, POP_TOP); - ADDOP(c, POP_TOP); - ADDOP(c, POP_EXCEPT); - ADDOP(c, POP_TOP); - return 1; -} - -/* - Implements the async with statement. - - The semantics outlined in that PEP are as follows: - - async with EXPR as VAR: - BLOCK - - It is implemented roughly as: - - context = EXPR - exit = context.__aexit__ # not calling it - value = await context.__aenter__() - try: - VAR = value # if VAR present in the syntax - BLOCK - finally: - if an exception was raised: - exc = copy of (exception, instance, traceback) - else: - exc = (None, None, None) - if not (await exit(*exc)): - raise - */ -static int -compiler_async_with(struct compiler *c, stmt_ty s, int pos) -{ - basicblock *block, *final, *exit; - withitem_ty item = asdl_seq_GET(s->v.AsyncWith.items, pos); - - assert(s->kind == AsyncWith_kind); - if (IS_TOP_LEVEL_AWAIT(c)){ - c->u->u_ste->ste_coroutine = 1; - } else if (c->u->u_scope_type != COMPILER_SCOPE_ASYNC_FUNCTION){ - return compiler_error(c, "'async with' outside async function"); - } - - block = compiler_new_block(c); - final = compiler_new_block(c); - exit = compiler_new_block(c); - if (!block || !final || !exit) - return 0; - - /* Evaluate EXPR */ - VISIT(c, expr, item->context_expr); - - ADDOP(c, BEFORE_ASYNC_WITH); - ADDOP(c, GET_AWAITABLE); - ADDOP_LOAD_CONST(c, Py_None); - ADDOP(c, YIELD_FROM); - - ADDOP_JUMP(c, SETUP_ASYNC_WITH, final); - - /* SETUP_ASYNC_WITH pushes a finally block. */ - compiler_use_next_block(c, block); - if (!compiler_push_fblock(c, ASYNC_WITH, block, final, s)) { - return 0; - } - - if (item->optional_vars) { - VISIT(c, expr, item->optional_vars); - } - else { - /* Discard result from context.__aenter__() */ - ADDOP(c, POP_TOP); - } - - pos++; - if (pos == asdl_seq_LEN(s->v.AsyncWith.items)) - /* BLOCK code */ - VISIT_SEQ(c, stmt, s->v.AsyncWith.body) - else if (!compiler_async_with(c, s, pos)) - return 0; - - compiler_pop_fblock(c, ASYNC_WITH, block); - ADDOP(c, POP_BLOCK); - /* End of body; start the cleanup */ - - /* For successful outcome: - * call __exit__(None, None, None) - */ - SET_LOC(c, s); - if(!compiler_call_exit_with_nones(c)) - return 0; - ADDOP(c, GET_AWAITABLE); - ADDOP_LOAD_CONST(c, Py_None); - ADDOP(c, YIELD_FROM); - - ADDOP(c, POP_TOP); - - ADDOP_JUMP(c, JUMP_ABSOLUTE, exit); - - /* For exceptional outcome: */ - compiler_use_next_block(c, final); - ADDOP(c, WITH_EXCEPT_START); - ADDOP(c, GET_AWAITABLE); - ADDOP_LOAD_CONST(c, Py_None); - ADDOP(c, YIELD_FROM); - compiler_with_except_finish(c); - -compiler_use_next_block(c, exit); - return 1; -} - - -/* - Implements the with statement from PEP 343. - with EXPR as VAR: - BLOCK - is implemented as: - <code for EXPR> - SETUP_WITH E - <code to store to VAR> or POP_TOP - <code for BLOCK> - LOAD_CONST (None, None, None) - CALL_FUNCTION_EX 0 - JUMP_FORWARD EXIT - E: WITH_EXCEPT_START (calls EXPR.__exit__) - POP_JUMP_IF_TRUE T: - RERAISE - T: POP_TOP * 3 (remove exception from stack) - POP_EXCEPT - POP_TOP - EXIT: - */ - -static int -compiler_with(struct compiler *c, stmt_ty s, int pos) -{ - basicblock *block, *final, *exit; - withitem_ty item = asdl_seq_GET(s->v.With.items, pos); - - assert(s->kind == With_kind); - - block = compiler_new_block(c); - final = compiler_new_block(c); - exit = compiler_new_block(c); - if (!block || !final || !exit) - return 0; - - /* Evaluate EXPR */ - VISIT(c, expr, item->context_expr); - /* Will push bound __exit__ */ - ADDOP_JUMP(c, SETUP_WITH, final); - - /* SETUP_WITH pushes a finally block. */ - compiler_use_next_block(c, block); - if (!compiler_push_fblock(c, WITH, block, final, s)) { - return 0; - } - - if (item->optional_vars) { - VISIT(c, expr, item->optional_vars); - } - else { - /* Discard result from context.__enter__() */ - ADDOP(c, POP_TOP); - } - - pos++; - if (pos == asdl_seq_LEN(s->v.With.items)) - /* BLOCK code */ - VISIT_SEQ(c, stmt, s->v.With.body) - else if (!compiler_with(c, s, pos)) - return 0; - - - /* Mark all following code as artificial */ - c->u->u_lineno = -1; - ADDOP(c, POP_BLOCK); - compiler_pop_fblock(c, WITH, block); - - /* End of body; start the cleanup. */ - - /* For successful outcome: - * call __exit__(None, None, None) - */ - SET_LOC(c, s); - if (!compiler_call_exit_with_nones(c)) - return 0; - ADDOP(c, POP_TOP); - ADDOP_JUMP(c, JUMP_FORWARD, exit); - - /* For exceptional outcome: */ - compiler_use_next_block(c, final); - ADDOP(c, WITH_EXCEPT_START); - compiler_with_except_finish(c); - - compiler_use_next_block(c, exit); - return 1; -} - -static int -compiler_visit_expr1(struct compiler *c, expr_ty e) -{ - switch (e->kind) { - case NamedExpr_kind: - VISIT(c, expr, e->v.NamedExpr.value); - ADDOP(c, DUP_TOP); - VISIT(c, expr, e->v.NamedExpr.target); - break; - case BoolOp_kind: - return compiler_boolop(c, e); - case BinOp_kind: - VISIT(c, expr, e->v.BinOp.left); - VISIT(c, expr, e->v.BinOp.right); - ADDOP(c, binop(e->v.BinOp.op)); - break; - case UnaryOp_kind: - VISIT(c, expr, e->v.UnaryOp.operand); - ADDOP(c, unaryop(e->v.UnaryOp.op)); - break; - case Lambda_kind: - return compiler_lambda(c, e); - case IfExp_kind: - return compiler_ifexp(c, e); - case Dict_kind: - return compiler_dict(c, e); - case Set_kind: - return compiler_set(c, e); - case GeneratorExp_kind: - return compiler_genexp(c, e); - case ListComp_kind: - return compiler_listcomp(c, e); - case SetComp_kind: - return compiler_setcomp(c, e); - case DictComp_kind: - return compiler_dictcomp(c, e); - case Yield_kind: - if (c->u->u_ste->ste_type != FunctionBlock) - return compiler_error(c, "'yield' outside function"); - if (e->v.Yield.value) { - VISIT(c, expr, e->v.Yield.value); - } - else { - ADDOP_LOAD_CONST(c, Py_None); - } - ADDOP(c, YIELD_VALUE); - break; - case YieldFrom_kind: - if (c->u->u_ste->ste_type != FunctionBlock) - return compiler_error(c, "'yield' outside function"); - - if (c->u->u_scope_type == COMPILER_SCOPE_ASYNC_FUNCTION) - return compiler_error(c, "'yield from' inside async function"); - - VISIT(c, expr, e->v.YieldFrom.value); - ADDOP(c, GET_YIELD_FROM_ITER); - ADDOP_LOAD_CONST(c, Py_None); - ADDOP(c, YIELD_FROM); - break; - case Await_kind: - if (!IS_TOP_LEVEL_AWAIT(c)){ - if (c->u->u_ste->ste_type != FunctionBlock){ - return compiler_error(c, "'await' outside function"); - } - - if (c->u->u_scope_type != COMPILER_SCOPE_ASYNC_FUNCTION && - c->u->u_scope_type != COMPILER_SCOPE_COMPREHENSION){ - return compiler_error(c, "'await' outside async function"); - } - } - - VISIT(c, expr, e->v.Await.value); - ADDOP(c, GET_AWAITABLE); - ADDOP_LOAD_CONST(c, Py_None); - ADDOP(c, YIELD_FROM); - break; - case Compare_kind: - return compiler_compare(c, e); - case Call_kind: - return compiler_call(c, e); - case Constant_kind: - ADDOP_LOAD_CONST(c, e->v.Constant.value); - break; - case JoinedStr_kind: - return compiler_joined_str(c, e); - case FormattedValue_kind: - return compiler_formatted_value(c, e); - /* The following exprs can be assignment targets. */ - case Attribute_kind: - VISIT(c, expr, e->v.Attribute.value); - switch (e->v.Attribute.ctx) { - case Load: - { - int old_lineno = c->u->u_lineno; - c->u->u_lineno = e->end_lineno; - ADDOP_NAME(c, LOAD_ATTR, e->v.Attribute.attr, names); - c->u->u_lineno = old_lineno; - break; - } - case Store: - if (forbidden_name(c, e->v.Attribute.attr, e->v.Attribute.ctx)) { - return 0; - } - int old_lineno = c->u->u_lineno; - c->u->u_lineno = e->end_lineno; - ADDOP_NAME(c, STORE_ATTR, e->v.Attribute.attr, names); - c->u->u_lineno = old_lineno; - break; - case Del: - ADDOP_NAME(c, DELETE_ATTR, e->v.Attribute.attr, names); - break; - } - break; - case Subscript_kind: - return compiler_subscript(c, e); - case Starred_kind: - switch (e->v.Starred.ctx) { - case Store: - /* In all legitimate cases, the Starred node was already replaced - * by compiler_list/compiler_tuple. XXX: is that okay? */ - return compiler_error(c, - "starred assignment target must be in a list or tuple"); - default: - return compiler_error(c, - "can't use starred expression here"); - } - break; - case Slice_kind: - return compiler_slice(c, e); - case Name_kind: - return compiler_nameop(c, e->v.Name.id, e->v.Name.ctx); - /* child nodes of List and Tuple will have expr_context set */ - case List_kind: - return compiler_list(c, e); - case Tuple_kind: - return compiler_tuple(c, e); - } - return 1; -} - -static int -compiler_visit_expr(struct compiler *c, expr_ty e) -{ - int old_lineno = c->u->u_lineno; - int old_end_lineno = c->u->u_end_lineno; - int old_col_offset = c->u->u_col_offset; - int old_end_col_offset = c->u->u_end_col_offset; - SET_LOC(c, e); - int res = compiler_visit_expr1(c, e); - c->u->u_lineno = old_lineno; - c->u->u_end_lineno = old_end_lineno; - c->u->u_col_offset = old_col_offset; - c->u->u_end_col_offset = old_end_col_offset; - return res; -} - -static int -compiler_augassign(struct compiler *c, stmt_ty s) -{ - assert(s->kind == AugAssign_kind); - expr_ty e = s->v.AugAssign.target; - - int old_lineno = c->u->u_lineno; - int old_end_lineno = c->u->u_end_lineno; - int old_col_offset = c->u->u_col_offset; - int old_end_col_offset = c->u->u_end_col_offset; - SET_LOC(c, e); - - switch (e->kind) { - case Attribute_kind: - VISIT(c, expr, e->v.Attribute.value); - ADDOP(c, DUP_TOP); - int old_lineno = c->u->u_lineno; - c->u->u_lineno = e->end_lineno; - ADDOP_NAME(c, LOAD_ATTR, e->v.Attribute.attr, names); - c->u->u_lineno = old_lineno; - break; - case Subscript_kind: - VISIT(c, expr, e->v.Subscript.value); - VISIT(c, expr, e->v.Subscript.slice); - ADDOP(c, DUP_TOP_TWO); - ADDOP(c, BINARY_SUBSCR); - break; - case Name_kind: - if (!compiler_nameop(c, e->v.Name.id, Load)) - return 0; - break; - default: - PyErr_Format(PyExc_SystemError, - "invalid node type (%d) for augmented assignment", - e->kind); - return 0; - } - - c->u->u_lineno = old_lineno; - c->u->u_end_lineno = old_end_lineno; - c->u->u_col_offset = old_col_offset; - c->u->u_end_col_offset = old_end_col_offset; - - VISIT(c, expr, s->v.AugAssign.value); - ADDOP(c, inplace_binop(s->v.AugAssign.op)); - - SET_LOC(c, e); - - switch (e->kind) { - case Attribute_kind: - c->u->u_lineno = e->end_lineno; - ADDOP(c, ROT_TWO); - ADDOP_NAME(c, STORE_ATTR, e->v.Attribute.attr, names); - break; - case Subscript_kind: - ADDOP(c, ROT_THREE); - ADDOP(c, STORE_SUBSCR); - break; - case Name_kind: - return compiler_nameop(c, e->v.Name.id, Store); - default: - Py_UNREACHABLE(); - } - return 1; -} - -static int -check_ann_expr(struct compiler *c, expr_ty e) -{ - VISIT(c, expr, e); - ADDOP(c, POP_TOP); - return 1; -} - -static int -check_annotation(struct compiler *c, stmt_ty s) -{ - /* Annotations of complex targets does not produce anything - under annotations future */ - if (c->c_future->ff_features & CO_FUTURE_ANNOTATIONS) { - return 1; - } - - /* Annotations are only evaluated in a module or class. */ - if (c->u->u_scope_type == COMPILER_SCOPE_MODULE || - c->u->u_scope_type == COMPILER_SCOPE_CLASS) { - return check_ann_expr(c, s->v.AnnAssign.annotation); - } - return 1; -} - -static int -check_ann_subscr(struct compiler *c, expr_ty e) -{ - /* We check that everything in a subscript is defined at runtime. */ - switch (e->kind) { - case Slice_kind: - if (e->v.Slice.lower && !check_ann_expr(c, e->v.Slice.lower)) { - return 0; - } - if (e->v.Slice.upper && !check_ann_expr(c, e->v.Slice.upper)) { - return 0; - } - if (e->v.Slice.step && !check_ann_expr(c, e->v.Slice.step)) { - return 0; - } - return 1; - case Tuple_kind: { - /* extended slice */ - asdl_expr_seq *elts = e->v.Tuple.elts; - Py_ssize_t i, n = asdl_seq_LEN(elts); - for (i = 0; i < n; i++) { - if (!check_ann_subscr(c, asdl_seq_GET(elts, i))) { - return 0; - } - } - return 1; - } - default: - return check_ann_expr(c, e); - } -} - -static int -compiler_annassign(struct compiler *c, stmt_ty s) -{ - expr_ty targ = s->v.AnnAssign.target; - PyObject* mangled; - - assert(s->kind == AnnAssign_kind); - - /* We perform the actual assignment first. */ - if (s->v.AnnAssign.value) { - VISIT(c, expr, s->v.AnnAssign.value); - VISIT(c, expr, targ); - } - switch (targ->kind) { - case Name_kind: - if (forbidden_name(c, targ->v.Name.id, Store)) - return 0; - /* If we have a simple name in a module or class, store annotation. */ - if (s->v.AnnAssign.simple && - (c->u->u_scope_type == COMPILER_SCOPE_MODULE || - c->u->u_scope_type == COMPILER_SCOPE_CLASS)) { - if (c->c_future->ff_features & CO_FUTURE_ANNOTATIONS) { - VISIT(c, annexpr, s->v.AnnAssign.annotation) - } - else { - VISIT(c, expr, s->v.AnnAssign.annotation); - } - ADDOP_NAME(c, LOAD_NAME, __annotations__, names); - mangled = _Py_Mangle(c->u->u_private, targ->v.Name.id); - ADDOP_LOAD_CONST_NEW(c, mangled); - ADDOP(c, STORE_SUBSCR); - } - break; - case Attribute_kind: - if (forbidden_name(c, targ->v.Attribute.attr, Store)) - return 0; - if (!s->v.AnnAssign.value && - !check_ann_expr(c, targ->v.Attribute.value)) { - return 0; - } - break; - case Subscript_kind: - if (!s->v.AnnAssign.value && - (!check_ann_expr(c, targ->v.Subscript.value) || - !check_ann_subscr(c, targ->v.Subscript.slice))) { - return 0; - } - break; - default: - PyErr_Format(PyExc_SystemError, - "invalid node type (%d) for annotated assignment", - targ->kind); - return 0; - } - /* Annotation is evaluated last. */ - if (!s->v.AnnAssign.simple && !check_annotation(c, s)) { - return 0; - } - return 1; -} - -/* Raises a SyntaxError and returns 0. - If something goes wrong, a different exception may be raised. -*/ - -static int -compiler_error(struct compiler *c, const char *format, ...) -{ - va_list vargs; -#ifdef HAVE_STDARG_PROTOTYPES - va_start(vargs, format); -#else - va_start(vargs); -#endif - PyObject *msg = PyUnicode_FromFormatV(format, vargs); - va_end(vargs); - if (msg == NULL) { - return 0; - } - PyObject *loc = PyErr_ProgramTextObject(c->c_filename, c->u->u_lineno); - if (loc == NULL) { - Py_INCREF(Py_None); - loc = Py_None; - } - PyObject *args = Py_BuildValue("O(OiiOii)", msg, c->c_filename, - c->u->u_lineno, c->u->u_col_offset + 1, loc, - c->u->u_end_lineno, c->u->u_end_col_offset + 1); - Py_DECREF(msg); - if (args == NULL) { - goto exit; - } - PyErr_SetObject(PyExc_SyntaxError, args); - exit: - Py_DECREF(loc); - Py_XDECREF(args); - return 0; -} - -/* Emits a SyntaxWarning and returns 1 on success. - If a SyntaxWarning raised as error, replaces it with a SyntaxError - and returns 0. -*/ -static int -compiler_warn(struct compiler *c, const char *format, ...) -{ - va_list vargs; -#ifdef HAVE_STDARG_PROTOTYPES - va_start(vargs, format); -#else - va_start(vargs); -#endif - PyObject *msg = PyUnicode_FromFormatV(format, vargs); - va_end(vargs); - if (msg == NULL) { - return 0; - } - if (PyErr_WarnExplicitObject(PyExc_SyntaxWarning, msg, c->c_filename, - c->u->u_lineno, NULL, NULL) < 0) - { - if (PyErr_ExceptionMatches(PyExc_SyntaxWarning)) { - /* Replace the SyntaxWarning exception with a SyntaxError - to get a more accurate error report */ - PyErr_Clear(); - assert(PyUnicode_AsUTF8(msg) != NULL); - compiler_error(c, PyUnicode_AsUTF8(msg)); - } - Py_DECREF(msg); - return 0; - } - Py_DECREF(msg); - return 1; -} - -static int -compiler_subscript(struct compiler *c, expr_ty e) -{ - expr_context_ty ctx = e->v.Subscript.ctx; - int op = 0; - - if (ctx == Load) { - if (!check_subscripter(c, e->v.Subscript.value)) { - return 0; - } - if (!check_index(c, e->v.Subscript.value, e->v.Subscript.slice)) { - return 0; - } - } - - switch (ctx) { - case Load: op = BINARY_SUBSCR; break; - case Store: op = STORE_SUBSCR; break; - case Del: op = DELETE_SUBSCR; break; - } - assert(op); - VISIT(c, expr, e->v.Subscript.value); - VISIT(c, expr, e->v.Subscript.slice); - ADDOP(c, op); - return 1; -} - -static int -compiler_slice(struct compiler *c, expr_ty s) -{ - int n = 2; - assert(s->kind == Slice_kind); - - /* only handles the cases where BUILD_SLICE is emitted */ - if (s->v.Slice.lower) { - VISIT(c, expr, s->v.Slice.lower); - } - else { - ADDOP_LOAD_CONST(c, Py_None); - } - - if (s->v.Slice.upper) { - VISIT(c, expr, s->v.Slice.upper); - } - else { - ADDOP_LOAD_CONST(c, Py_None); - } - - if (s->v.Slice.step) { - n++; - VISIT(c, expr, s->v.Slice.step); - } - ADDOP_I(c, BUILD_SLICE, n); - return 1; -} - - -// PEP 634: Structural Pattern Matching - -// To keep things simple, all compiler_pattern_* and pattern_helper_* routines -// follow the convention of consuming TOS (the subject for the given pattern) -// and calling jump_to_fail_pop on failure (no match). - -// When calling into these routines, it's important that pc->on_top be kept -// updated to reflect the current number of items that we are using on the top -// of the stack: they will be popped on failure, and any name captures will be -// stored *underneath* them on success. This lets us defer all names stores -// until the *entire* pattern matches. - -#define WILDCARD_CHECK(N) \ - ((N)->kind == MatchAs_kind && !(N)->v.MatchAs.name) - -#define WILDCARD_STAR_CHECK(N) \ - ((N)->kind == MatchStar_kind && !(N)->v.MatchStar.name) - -// Limit permitted subexpressions, even if the parser & AST validator let them through -#define MATCH_VALUE_EXPR(N) \ - ((N)->kind == Constant_kind || (N)->kind == Attribute_kind) - -// Allocate or resize pc->fail_pop to allow for n items to be popped on failure. -static int -ensure_fail_pop(struct compiler *c, pattern_context *pc, Py_ssize_t n) -{ - Py_ssize_t size = n + 1; - if (size <= pc->fail_pop_size) { - return 1; - } - Py_ssize_t needed = sizeof(basicblock*) * size; - basicblock **resized = PyObject_Realloc(pc->fail_pop, needed); - if (resized == NULL) { - PyErr_NoMemory(); - return 0; - } - pc->fail_pop = resized; - while (pc->fail_pop_size < size) { - basicblock *new_block; - RETURN_IF_FALSE(new_block = compiler_new_block(c)); - pc->fail_pop[pc->fail_pop_size++] = new_block; - } - return 1; -} - -// Use op to jump to the correct fail_pop block. -static int -jump_to_fail_pop(struct compiler *c, pattern_context *pc, int op) -{ - // Pop any items on the top of the stack, plus any objects we were going to - // capture on success: - Py_ssize_t pops = pc->on_top + PyList_GET_SIZE(pc->stores); - RETURN_IF_FALSE(ensure_fail_pop(c, pc, pops)); - ADDOP_JUMP(c, op, pc->fail_pop[pops]); - NEXT_BLOCK(c); - return 1; -} - -// Build all of the fail_pop blocks and reset fail_pop. -static int -emit_and_reset_fail_pop(struct compiler *c, pattern_context *pc) -{ - if (!pc->fail_pop_size) { - assert(pc->fail_pop == NULL); - NEXT_BLOCK(c); - return 1; - } - while (--pc->fail_pop_size) { - compiler_use_next_block(c, pc->fail_pop[pc->fail_pop_size]); - if (!compiler_addop(c, POP_TOP)) { - pc->fail_pop_size = 0; - PyObject_Free(pc->fail_pop); - pc->fail_pop = NULL; - return 0; - } - } - compiler_use_next_block(c, pc->fail_pop[0]); - PyObject_Free(pc->fail_pop); - pc->fail_pop = NULL; - return 1; -} - -static int -compiler_error_duplicate_store(struct compiler *c, identifier n) -{ - return compiler_error(c, "multiple assignments to name %R in pattern", n); -} - -static int -pattern_helper_store_name(struct compiler *c, identifier n, pattern_context *pc) -{ - if (n == NULL) { - ADDOP(c, POP_TOP); - return 1; - } - if (forbidden_name(c, n, Store)) { - return 0; - } - // Can't assign to the same name twice: - int duplicate = PySequence_Contains(pc->stores, n); - if (duplicate < 0) { - return 0; - } - if (duplicate) { - return compiler_error_duplicate_store(c, n); - } - // Rotate this object underneath any items we need to preserve: - ADDOP_I(c, ROT_N, pc->on_top + PyList_GET_SIZE(pc->stores) + 1); - return !PyList_Append(pc->stores, n); -} - - -static int -pattern_unpack_helper(struct compiler *c, asdl_pattern_seq *elts) -{ - Py_ssize_t n = asdl_seq_LEN(elts); - int seen_star = 0; - for (Py_ssize_t i = 0; i < n; i++) { - pattern_ty elt = asdl_seq_GET(elts, i); - if (elt->kind == MatchStar_kind && !seen_star) { - if ((i >= (1 << 8)) || - (n-i-1 >= (INT_MAX >> 8))) - return compiler_error(c, - "too many expressions in " - "star-unpacking sequence pattern"); - ADDOP_I(c, UNPACK_EX, (i + ((n-i-1) << 8))); - seen_star = 1; - } - else if (elt->kind == MatchStar_kind) { - return compiler_error(c, - "multiple starred expressions in sequence pattern"); - } - } - if (!seen_star) { - ADDOP_I(c, UNPACK_SEQUENCE, n); - } - return 1; -} - -static int -pattern_helper_sequence_unpack(struct compiler *c, asdl_pattern_seq *patterns, - Py_ssize_t star, pattern_context *pc) -{ - RETURN_IF_FALSE(pattern_unpack_helper(c, patterns)); - Py_ssize_t size = asdl_seq_LEN(patterns); - // We've now got a bunch of new subjects on the stack. They need to remain - // there after each subpattern match: - pc->on_top += size; - for (Py_ssize_t i = 0; i < size; i++) { - // One less item to keep track of each time we loop through: - pc->on_top--; - pattern_ty pattern = asdl_seq_GET(patterns, i); - RETURN_IF_FALSE(compiler_pattern_subpattern(c, pattern, pc)); - } - return 1; -} - -// Like pattern_helper_sequence_unpack, but uses BINARY_SUBSCR instead of -// UNPACK_SEQUENCE / UNPACK_EX. This is more efficient for patterns with a -// starred wildcard like [first, *_] / [first, *_, last] / [*_, last] / etc. -static int -pattern_helper_sequence_subscr(struct compiler *c, asdl_pattern_seq *patterns, - Py_ssize_t star, pattern_context *pc) -{ - // We need to keep the subject around for extracting elements: - pc->on_top++; - Py_ssize_t size = asdl_seq_LEN(patterns); - for (Py_ssize_t i = 0; i < size; i++) { - pattern_ty pattern = asdl_seq_GET(patterns, i); - if (WILDCARD_CHECK(pattern)) { - continue; - } - if (i == star) { - assert(WILDCARD_STAR_CHECK(pattern)); - continue; - } - ADDOP(c, DUP_TOP); - if (i < star) { - ADDOP_LOAD_CONST_NEW(c, PyLong_FromSsize_t(i)); - } - else { - // The subject may not support negative indexing! Compute a - // nonnegative index: - ADDOP(c, GET_LEN); - ADDOP_LOAD_CONST_NEW(c, PyLong_FromSsize_t(size - i)); - ADDOP(c, BINARY_SUBTRACT); - } - ADDOP(c, BINARY_SUBSCR); - RETURN_IF_FALSE(compiler_pattern_subpattern(c, pattern, pc)); - } - // Pop the subject, we're done with it: - pc->on_top--; - ADDOP(c, POP_TOP); - return 1; -} - -// Like compiler_pattern, but turn off checks for irrefutability. -static int -compiler_pattern_subpattern(struct compiler *c, pattern_ty p, pattern_context *pc) -{ - int allow_irrefutable = pc->allow_irrefutable; - pc->allow_irrefutable = 1; - RETURN_IF_FALSE(compiler_pattern(c, p, pc)); - pc->allow_irrefutable = allow_irrefutable; - return 1; -} - -static int -compiler_pattern_as(struct compiler *c, pattern_ty p, pattern_context *pc) -{ - assert(p->kind == MatchAs_kind); - if (p->v.MatchAs.pattern == NULL) { - // An irrefutable match: - if (!pc->allow_irrefutable) { - if (p->v.MatchAs.name) { - const char *e = "name capture %R makes remaining patterns unreachable"; - return compiler_error(c, e, p->v.MatchAs.name); - } - const char *e = "wildcard makes remaining patterns unreachable"; - return compiler_error(c, e); - } - return pattern_helper_store_name(c, p->v.MatchAs.name, pc); - } - // Need to make a copy for (possibly) storing later: - pc->on_top++; - ADDOP(c, DUP_TOP); - RETURN_IF_FALSE(compiler_pattern(c, p->v.MatchAs.pattern, pc)); - // Success! Store it: - pc->on_top--; - RETURN_IF_FALSE(pattern_helper_store_name(c, p->v.MatchAs.name, pc)); - return 1; -} - -static int -compiler_pattern_star(struct compiler *c, pattern_ty p, pattern_context *pc) -{ - assert(p->kind == MatchStar_kind); - RETURN_IF_FALSE(pattern_helper_store_name(c, p->v.MatchStar.name, pc)); - return 1; -} - -static int -validate_kwd_attrs(struct compiler *c, asdl_identifier_seq *attrs, asdl_pattern_seq* patterns) -{ - // Any errors will point to the pattern rather than the arg name as the - // parser is only supplying identifiers rather than Name or keyword nodes - Py_ssize_t nattrs = asdl_seq_LEN(attrs); - for (Py_ssize_t i = 0; i < nattrs; i++) { - identifier attr = ((identifier)asdl_seq_GET(attrs, i)); - SET_LOC(c, ((pattern_ty) asdl_seq_GET(patterns, i))); - if (forbidden_name(c, attr, Store)) { - return -1; - } - for (Py_ssize_t j = i + 1; j < nattrs; j++) { - identifier other = ((identifier)asdl_seq_GET(attrs, j)); - if (!PyUnicode_Compare(attr, other)) { - SET_LOC(c, ((pattern_ty) asdl_seq_GET(patterns, j))); - compiler_error(c, "attribute name repeated in class pattern: %U", attr); - return -1; - } - } - } - return 0; -} - -static int -compiler_pattern_class(struct compiler *c, pattern_ty p, pattern_context *pc) -{ - assert(p->kind == MatchClass_kind); - asdl_pattern_seq *patterns = p->v.MatchClass.patterns; - asdl_identifier_seq *kwd_attrs = p->v.MatchClass.kwd_attrs; - asdl_pattern_seq *kwd_patterns = p->v.MatchClass.kwd_patterns; - Py_ssize_t nargs = asdl_seq_LEN(patterns); - Py_ssize_t nattrs = asdl_seq_LEN(kwd_attrs); - Py_ssize_t nkwd_patterns = asdl_seq_LEN(kwd_patterns); - if (nattrs != nkwd_patterns) { - // AST validator shouldn't let this happen, but if it does, - // just fail, don't crash out of the interpreter - const char * e = "kwd_attrs (%d) / kwd_patterns (%d) length mismatch in class pattern"; - return compiler_error(c, e, nattrs, nkwd_patterns); - } - if (INT_MAX < nargs || INT_MAX < nargs + nattrs - 1) { - const char *e = "too many sub-patterns in class pattern %R"; - return compiler_error(c, e, p->v.MatchClass.cls); - } - if (nattrs) { - RETURN_IF_FALSE(!validate_kwd_attrs(c, kwd_attrs, kwd_patterns)); - SET_LOC(c, p); - } - VISIT(c, expr, p->v.MatchClass.cls); - PyObject *attr_names; - RETURN_IF_FALSE(attr_names = PyTuple_New(nattrs)); - Py_ssize_t i; - for (i = 0; i < nattrs; i++) { - PyObject *name = asdl_seq_GET(kwd_attrs, i); - Py_INCREF(name); - PyTuple_SET_ITEM(attr_names, i, name); - } - ADDOP_LOAD_CONST_NEW(c, attr_names); - ADDOP_I(c, MATCH_CLASS, nargs); - // TOS is now a tuple of (nargs + nattrs) attributes. Preserve it: - pc->on_top++; - RETURN_IF_FALSE(jump_to_fail_pop(c, pc, POP_JUMP_IF_FALSE)); - for (i = 0; i < nargs + nattrs; i++) { - pattern_ty pattern; - if (i < nargs) { - // Positional: - pattern = asdl_seq_GET(patterns, i); - } - else { - // Keyword: - pattern = asdl_seq_GET(kwd_patterns, i - nargs); - } - if (WILDCARD_CHECK(pattern)) { - continue; - } - // Get the i-th attribute, and match it against the i-th pattern: - ADDOP(c, DUP_TOP); - ADDOP_LOAD_CONST_NEW(c, PyLong_FromSsize_t(i)); - ADDOP(c, BINARY_SUBSCR); - RETURN_IF_FALSE(compiler_pattern_subpattern(c, pattern, pc)); - } - // Success! Pop the tuple of attributes: - pc->on_top--; - ADDOP(c, POP_TOP); - return 1; -} - -static int -compiler_pattern_mapping(struct compiler *c, pattern_ty p, pattern_context *pc) -{ - assert(p->kind == MatchMapping_kind); - asdl_expr_seq *keys = p->v.MatchMapping.keys; - asdl_pattern_seq *patterns = p->v.MatchMapping.patterns; - Py_ssize_t size = asdl_seq_LEN(keys); - Py_ssize_t npatterns = asdl_seq_LEN(patterns); - if (size != npatterns) { - // AST validator shouldn't let this happen, but if it does, - // just fail, don't crash out of the interpreter - const char * e = "keys (%d) / patterns (%d) length mismatch in mapping pattern"; - return compiler_error(c, e, size, npatterns); - } - // We have a double-star target if "rest" is set - PyObject *star_target = p->v.MatchMapping.rest; - // We need to keep the subject on top during the mapping and length checks: - pc->on_top++; - ADDOP(c, MATCH_MAPPING); - RETURN_IF_FALSE(jump_to_fail_pop(c, pc, POP_JUMP_IF_FALSE)); - if (!size && !star_target) { - // If the pattern is just "{}", we're done! Pop the subject: - pc->on_top--; - ADDOP(c, POP_TOP); - return 1; - } - if (size) { - // If the pattern has any keys in it, perform a length check: - ADDOP(c, GET_LEN); - ADDOP_LOAD_CONST_NEW(c, PyLong_FromSsize_t(size)); - ADDOP_COMPARE(c, GtE); - RETURN_IF_FALSE(jump_to_fail_pop(c, pc, POP_JUMP_IF_FALSE)); - } - if (INT_MAX < size - 1) { - return compiler_error(c, "too many sub-patterns in mapping pattern"); - } - // Collect all of the keys into a tuple for MATCH_KEYS and - // COPY_DICT_WITHOUT_KEYS. They can either be dotted names or literals: - - // Maintaining a set of Constant_kind kind keys allows us to raise a - // SyntaxError in the case of duplicates. - PyObject *seen = PySet_New(NULL); - if (seen == NULL) { - return 0; - } - - // NOTE: goto error on failure in the loop below to avoid leaking `seen` - for (Py_ssize_t i = 0; i < size; i++) { - expr_ty key = asdl_seq_GET(keys, i); - if (key == NULL) { - const char *e = "can't use NULL keys in MatchMapping " - "(set 'rest' parameter instead)"; - SET_LOC(c, ((pattern_ty) asdl_seq_GET(patterns, i))); - compiler_error(c, e); - goto error; - } - - if (key->kind == Constant_kind) { - int in_seen = PySet_Contains(seen, key->v.Constant.value); - if (in_seen < 0) { - goto error; - } - if (in_seen) { - const char *e = "mapping pattern checks duplicate key (%R)"; - compiler_error(c, e, key->v.Constant.value); - goto error; - } - if (PySet_Add(seen, key->v.Constant.value)) { - goto error; - } - } - - else if (key->kind != Attribute_kind) { - const char *e = "mapping pattern keys may only match literals and attribute lookups"; - compiler_error(c, e); - goto error; - } - if (!compiler_visit_expr(c, key)) { - goto error; - } - } - - // all keys have been checked; there are no duplicates - Py_DECREF(seen); - - ADDOP_I(c, BUILD_TUPLE, size); - ADDOP(c, MATCH_KEYS); - // There's now a tuple of keys and a tuple of values on top of the subject: - pc->on_top += 2; - RETURN_IF_FALSE(jump_to_fail_pop(c, pc, POP_JUMP_IF_FALSE)); - // So far so good. Use that tuple of values on the stack to match - // sub-patterns against: - for (Py_ssize_t i = 0; i < size; i++) { - pattern_ty pattern = asdl_seq_GET(patterns, i); - if (WILDCARD_CHECK(pattern)) { - continue; - } - ADDOP(c, DUP_TOP); - ADDOP_LOAD_CONST_NEW(c, PyLong_FromSsize_t(i)); - ADDOP(c, BINARY_SUBSCR); - RETURN_IF_FALSE(compiler_pattern_subpattern(c, pattern, pc)); - } - // If we get this far, it's a match! We're done with the tuple of values, - // and whatever happens next should consume the tuple of keys underneath it: - pc->on_top -= 2; - ADDOP(c, POP_TOP); - if (star_target) { - // If we have a starred name, bind a dict of remaining items to it: - ADDOP(c, COPY_DICT_WITHOUT_KEYS); - RETURN_IF_FALSE(pattern_helper_store_name(c, star_target, pc)); - } - else { - // Otherwise, we don't care about this tuple of keys anymore: - ADDOP(c, POP_TOP); - } - // Pop the subject: - pc->on_top--; - ADDOP(c, POP_TOP); - return 1; - -error: - Py_DECREF(seen); - return 0; -} - -static int -compiler_pattern_or(struct compiler *c, pattern_ty p, pattern_context *pc) -{ - assert(p->kind == MatchOr_kind); - basicblock *end; - RETURN_IF_FALSE(end = compiler_new_block(c)); - Py_ssize_t size = asdl_seq_LEN(p->v.MatchOr.patterns); - assert(size > 1); - // We're going to be messing with pc. Keep the original info handy: - pattern_context old_pc = *pc; - Py_INCREF(pc->stores); - // control is the list of names bound by the first alternative. It is used - // for checking different name bindings in alternatives, and for correcting - // the order in which extracted elements are placed on the stack. - PyObject *control = NULL; - // NOTE: We can't use returning macros anymore! goto error on error. - for (Py_ssize_t i = 0; i < size; i++) { - pattern_ty alt = asdl_seq_GET(p->v.MatchOr.patterns, i); - SET_LOC(c, alt); - PyObject *pc_stores = PyList_New(0); - if (pc_stores == NULL) { - goto error; - } - Py_SETREF(pc->stores, pc_stores); - // An irrefutable sub-pattern must be last, if it is allowed at all: - pc->allow_irrefutable = (i == size - 1) && old_pc.allow_irrefutable; - pc->fail_pop = NULL; - pc->fail_pop_size = 0; - pc->on_top = 0; - if (!compiler_addop(c, DUP_TOP) || !compiler_pattern(c, alt, pc)) { - goto error; - } - // Success! - Py_ssize_t nstores = PyList_GET_SIZE(pc->stores); - if (!i) { - // This is the first alternative, so save its stores as a "control" - // for the others (they can't bind a different set of names, and - // might need to be reordered): - assert(control == NULL); - control = pc->stores; - Py_INCREF(control); - } - else if (nstores != PyList_GET_SIZE(control)) { - goto diff; - } - else if (nstores) { - // There were captures. Check to see if we differ from control: - Py_ssize_t icontrol = nstores; - while (icontrol--) { - PyObject *name = PyList_GET_ITEM(control, icontrol); - Py_ssize_t istores = PySequence_Index(pc->stores, name); - if (istores < 0) { - PyErr_Clear(); - goto diff; - } - if (icontrol != istores) { - // Reorder the names on the stack to match the order of the - // names in control. There's probably a better way of doing - // this; the current solution is potentially very - // inefficient when each alternative subpattern binds lots - // of names in different orders. It's fine for reasonable - // cases, though. - assert(istores < icontrol); - Py_ssize_t rotations = istores + 1; - // Perform the same rotation on pc->stores: - PyObject *rotated = PyList_GetSlice(pc->stores, 0, - rotations); - if (rotated == NULL || - PyList_SetSlice(pc->stores, 0, rotations, NULL) || - PyList_SetSlice(pc->stores, icontrol - istores, - icontrol - istores, rotated)) - { - Py_XDECREF(rotated); - goto error; - } - Py_DECREF(rotated); - // That just did: - // rotated = pc_stores[:rotations] - // del pc_stores[:rotations] - // pc_stores[icontrol-istores:icontrol-istores] = rotated - // Do the same thing to the stack, using several ROT_Ns: - while (rotations--) { - if (!compiler_addop_i(c, ROT_N, icontrol + 1)) { - goto error; - } - } - } - } - } - assert(control); - if (!compiler_addop_j(c, JUMP_FORWARD, end) || - !compiler_next_block(c) || - !emit_and_reset_fail_pop(c, pc)) - { - goto error; - } - } - Py_DECREF(pc->stores); - *pc = old_pc; - Py_INCREF(pc->stores); - // Need to NULL this for the PyObject_Free call in the error block. - old_pc.fail_pop = NULL; - // No match. Pop the remaining copy of the subject and fail: - if (!compiler_addop(c, POP_TOP) || !jump_to_fail_pop(c, pc, JUMP_FORWARD)) { - goto error; - } - compiler_use_next_block(c, end); - Py_ssize_t nstores = PyList_GET_SIZE(control); - // There's a bunch of stuff on the stack between any where the new stores - // are and where they need to be: - // - The other stores. - // - A copy of the subject. - // - Anything else that may be on top of the stack. - // - Any previous stores we've already stashed away on the stack. - Py_ssize_t nrots = nstores + 1 + pc->on_top + PyList_GET_SIZE(pc->stores); - for (Py_ssize_t i = 0; i < nstores; i++) { - // Rotate this capture to its proper place on the stack: - if (!compiler_addop_i(c, ROT_N, nrots)) { - goto error; - } - // Update the list of previous stores with this new name, checking for - // duplicates: - PyObject *name = PyList_GET_ITEM(control, i); - int dupe = PySequence_Contains(pc->stores, name); - if (dupe < 0) { - goto error; - } - if (dupe) { - compiler_error_duplicate_store(c, name); - goto error; - } - if (PyList_Append(pc->stores, name)) { - goto error; - } - } - Py_DECREF(old_pc.stores); - Py_DECREF(control); - // NOTE: Returning macros are safe again. - // Pop the copy of the subject: - ADDOP(c, POP_TOP); - return 1; -diff: - compiler_error(c, "alternative patterns bind different names"); -error: - PyObject_Free(old_pc.fail_pop); - Py_DECREF(old_pc.stores); - Py_XDECREF(control); - return 0; -} - - -static int -compiler_pattern_sequence(struct compiler *c, pattern_ty p, pattern_context *pc) -{ - assert(p->kind == MatchSequence_kind); - asdl_pattern_seq *patterns = p->v.MatchSequence.patterns; - Py_ssize_t size = asdl_seq_LEN(patterns); - Py_ssize_t star = -1; - int only_wildcard = 1; - int star_wildcard = 0; - // Find a starred name, if it exists. There may be at most one: - for (Py_ssize_t i = 0; i < size; i++) { - pattern_ty pattern = asdl_seq_GET(patterns, i); - if (pattern->kind == MatchStar_kind) { - if (star >= 0) { - const char *e = "multiple starred names in sequence pattern"; - return compiler_error(c, e); - } - star_wildcard = WILDCARD_STAR_CHECK(pattern); - only_wildcard &= star_wildcard; - star = i; - continue; - } - only_wildcard &= WILDCARD_CHECK(pattern); - } - // We need to keep the subject on top during the sequence and length checks: - pc->on_top++; - ADDOP(c, MATCH_SEQUENCE); - RETURN_IF_FALSE(jump_to_fail_pop(c, pc, POP_JUMP_IF_FALSE)); - if (star < 0) { - // No star: len(subject) == size - ADDOP(c, GET_LEN); - ADDOP_LOAD_CONST_NEW(c, PyLong_FromSsize_t(size)); - ADDOP_COMPARE(c, Eq); - RETURN_IF_FALSE(jump_to_fail_pop(c, pc, POP_JUMP_IF_FALSE)); - } - else if (size > 1) { - // Star: len(subject) >= size - 1 - ADDOP(c, GET_LEN); - ADDOP_LOAD_CONST_NEW(c, PyLong_FromSsize_t(size - 1)); - ADDOP_COMPARE(c, GtE); - RETURN_IF_FALSE(jump_to_fail_pop(c, pc, POP_JUMP_IF_FALSE)); - } - // Whatever comes next should consume the subject: - pc->on_top--; - if (only_wildcard) { - // Patterns like: [] / [_] / [_, _] / [*_] / [_, *_] / [_, _, *_] / etc. - ADDOP(c, POP_TOP); - } - else if (star_wildcard) { - RETURN_IF_FALSE(pattern_helper_sequence_subscr(c, patterns, star, pc)); - } - else { - RETURN_IF_FALSE(pattern_helper_sequence_unpack(c, patterns, star, pc)); - } - return 1; -} - -static int -compiler_pattern_value(struct compiler *c, pattern_ty p, pattern_context *pc) -{ - assert(p->kind == MatchValue_kind); - expr_ty value = p->v.MatchValue.value; - if (!MATCH_VALUE_EXPR(value)) { - const char *e = "patterns may only match literals and attribute lookups"; - return compiler_error(c, e); - } - VISIT(c, expr, value); - ADDOP_COMPARE(c, Eq); - RETURN_IF_FALSE(jump_to_fail_pop(c, pc, POP_JUMP_IF_FALSE)); - return 1; -} - -static int -compiler_pattern_singleton(struct compiler *c, pattern_ty p, pattern_context *pc) -{ - assert(p->kind == MatchSingleton_kind); - ADDOP_LOAD_CONST(c, p->v.MatchSingleton.value); - ADDOP_COMPARE(c, Is); - RETURN_IF_FALSE(jump_to_fail_pop(c, pc, POP_JUMP_IF_FALSE)); - return 1; -} - -static int -compiler_pattern(struct compiler *c, pattern_ty p, pattern_context *pc) -{ - SET_LOC(c, p); - switch (p->kind) { - case MatchValue_kind: - return compiler_pattern_value(c, p, pc); - case MatchSingleton_kind: - return compiler_pattern_singleton(c, p, pc); - case MatchSequence_kind: - return compiler_pattern_sequence(c, p, pc); - case MatchMapping_kind: - return compiler_pattern_mapping(c, p, pc); - case MatchClass_kind: - return compiler_pattern_class(c, p, pc); - case MatchStar_kind: - return compiler_pattern_star(c, p, pc); - case MatchAs_kind: - return compiler_pattern_as(c, p, pc); - case MatchOr_kind: - return compiler_pattern_or(c, p, pc); - } - // AST validator shouldn't let this happen, but if it does, - // just fail, don't crash out of the interpreter - const char *e = "invalid match pattern node in AST (kind=%d)"; - return compiler_error(c, e, p->kind); -} - -static int -compiler_match_inner(struct compiler *c, stmt_ty s, pattern_context *pc) -{ - VISIT(c, expr, s->v.Match.subject); - basicblock *end; - RETURN_IF_FALSE(end = compiler_new_block(c)); - Py_ssize_t cases = asdl_seq_LEN(s->v.Match.cases); - assert(cases > 0); - match_case_ty m = asdl_seq_GET(s->v.Match.cases, cases - 1); - int has_default = WILDCARD_CHECK(m->pattern) && 1 < cases; - for (Py_ssize_t i = 0; i < cases - has_default; i++) { - m = asdl_seq_GET(s->v.Match.cases, i); - SET_LOC(c, m->pattern); - // Only copy the subject if we're *not* on the last case: - if (i != cases - has_default - 1) { - ADDOP(c, DUP_TOP); - } - RETURN_IF_FALSE(pc->stores = PyList_New(0)); - // Irrefutable cases must be either guarded, last, or both: - pc->allow_irrefutable = m->guard != NULL || i == cases - 1; - pc->fail_pop = NULL; - pc->fail_pop_size = 0; - pc->on_top = 0; - // NOTE: Can't use returning macros here (they'll leak pc->stores)! - if (!compiler_pattern(c, m->pattern, pc)) { - Py_DECREF(pc->stores); - return 0; - } - assert(!pc->on_top); - // It's a match! Store all of the captured names (they're on the stack). - Py_ssize_t nstores = PyList_GET_SIZE(pc->stores); - for (Py_ssize_t n = 0; n < nstores; n++) { - PyObject *name = PyList_GET_ITEM(pc->stores, n); - if (!compiler_nameop(c, name, Store)) { - Py_DECREF(pc->stores); - return 0; - } - } - Py_DECREF(pc->stores); - // NOTE: Returning macros are safe again. - if (m->guard) { - RETURN_IF_FALSE(ensure_fail_pop(c, pc, 0)); - RETURN_IF_FALSE(compiler_jump_if(c, m->guard, pc->fail_pop[0], 0)); - } - // Success! Pop the subject off, we're done with it: - if (i != cases - has_default - 1) { - ADDOP(c, POP_TOP); - } - VISIT_SEQ(c, stmt, m->body); - ADDOP_JUMP(c, JUMP_FORWARD, end); - // If the pattern fails to match, we want the line number of the - // cleanup to be associated with the failed pattern, not the last line - // of the body - SET_LOC(c, m->pattern); - RETURN_IF_FALSE(emit_and_reset_fail_pop(c, pc)); - } - if (has_default) { - // A trailing "case _" is common, and lets us save a bit of redundant - // pushing and popping in the loop above: - m = asdl_seq_GET(s->v.Match.cases, cases - 1); - SET_LOC(c, m->pattern); - if (cases == 1) { - // No matches. Done with the subject: - ADDOP(c, POP_TOP); - } - else { - // Show line coverage for default case (it doesn't create bytecode) - ADDOP(c, NOP); - } - if (m->guard) { - RETURN_IF_FALSE(compiler_jump_if(c, m->guard, end, 0)); - } - VISIT_SEQ(c, stmt, m->body); - } - compiler_use_next_block(c, end); - return 1; -} - -static int -compiler_match(struct compiler *c, stmt_ty s) -{ - pattern_context pc; - pc.fail_pop = NULL; - int result = compiler_match_inner(c, s, &pc); - PyObject_Free(pc.fail_pop); - return result; -} - -#undef WILDCARD_CHECK -#undef WILDCARD_STAR_CHECK - -/* End of the compiler section, beginning of the assembler section */ - -/* do depth-first search of basic block graph, starting with block. - post records the block indices in post-order. - - XXX must handle implicit jumps from one block to next -*/ - -struct assembler { - PyObject *a_bytecode; /* string containing bytecode */ - int a_offset; /* offset into bytecode */ - int a_nblocks; /* number of reachable blocks */ - PyObject *a_lnotab; /* string containing lnotab */ - int a_lnotab_off; /* offset into lnotab */ - int a_prevlineno; /* lineno of last emitted line in line table */ - int a_lineno; /* lineno of last emitted instruction */ - int a_lineno_start; /* bytecode start offset of current lineno */ - basicblock *a_entry; -}; - -Py_LOCAL_INLINE(void) -stackdepth_push(basicblock ***sp, basicblock *b, int depth) -{ - assert(b->b_startdepth < 0 || b->b_startdepth == depth); - if (b->b_startdepth < depth && b->b_startdepth < 100) { - assert(b->b_startdepth < 0); - b->b_startdepth = depth; - *(*sp)++ = b; - } -} - -/* Find the flow path that needs the largest stack. We assume that - * cycles in the flow graph have no net effect on the stack depth. - */ -static int -stackdepth(struct compiler *c) -{ - basicblock *b, *entryblock = NULL; - basicblock **stack, **sp; - int nblocks = 0, maxdepth = 0; - for (b = c->u->u_blocks; b != NULL; b = b->b_list) { - b->b_startdepth = INT_MIN; - entryblock = b; - nblocks++; - } - assert(entryblock!= NULL); - stack = (basicblock **)PyObject_Malloc(sizeof(basicblock *) * nblocks); - if (!stack) { - PyErr_NoMemory(); - return -1; - } - - sp = stack; - if (c->u->u_ste->ste_generator || c->u->u_ste->ste_coroutine) { - stackdepth_push(&sp, entryblock, 1); - } else { - stackdepth_push(&sp, entryblock, 0); - } - while (sp != stack) { - b = *--sp; - int depth = b->b_startdepth; - assert(depth >= 0); - basicblock *next = b->b_next; - for (int i = 0; i < b->b_iused; i++) { - struct instr *instr = &b->b_instr[i]; - int effect = stack_effect(instr->i_opcode, instr->i_oparg, 0); - if (effect == PY_INVALID_STACK_EFFECT) { - PyErr_Format(PyExc_SystemError, - "compiler stack_effect(opcode=%d, arg=%i) failed", - instr->i_opcode, instr->i_oparg); - return -1; - } - int new_depth = depth + effect; - if (new_depth > maxdepth) { - maxdepth = new_depth; - } - assert(depth >= 0); /* invalid code or bug in stackdepth() */ - if (is_jump(instr)) { - effect = stack_effect(instr->i_opcode, instr->i_oparg, 1); - assert(effect != PY_INVALID_STACK_EFFECT); - int target_depth = depth + effect; - if (target_depth > maxdepth) { - maxdepth = target_depth; - } - assert(target_depth >= 0); /* invalid code or bug in stackdepth() */ - stackdepth_push(&sp, instr->i_target, target_depth); - } - depth = new_depth; - if (instr->i_opcode == JUMP_ABSOLUTE || - instr->i_opcode == JUMP_FORWARD || - instr->i_opcode == RETURN_VALUE || - instr->i_opcode == RAISE_VARARGS || - instr->i_opcode == RERAISE) - { - /* remaining code is dead */ - next = NULL; - break; - } - } - if (next != NULL) { - assert(b->b_nofallthrough == 0); - stackdepth_push(&sp, next, depth); - } - } - PyObject_Free(stack); - return maxdepth; -} - -static int -assemble_init(struct assembler *a, int nblocks, int firstlineno) -{ - memset(a, 0, sizeof(struct assembler)); - a->a_prevlineno = a->a_lineno = firstlineno; - a->a_lnotab = NULL; - a->a_bytecode = PyBytes_FromStringAndSize(NULL, DEFAULT_CODE_SIZE); - if (a->a_bytecode == NULL) { - goto error; - } - a->a_lnotab = PyBytes_FromStringAndSize(NULL, DEFAULT_LNOTAB_SIZE); - if (a->a_lnotab == NULL) { - goto error; - } - if ((size_t)nblocks > SIZE_MAX / sizeof(basicblock *)) { - PyErr_NoMemory(); - goto error; - } - return 1; -error: - Py_XDECREF(a->a_bytecode); - Py_XDECREF(a->a_lnotab); - return 0; -} - -static void -assemble_free(struct assembler *a) -{ - Py_XDECREF(a->a_bytecode); - Py_XDECREF(a->a_lnotab); -} - -static int -blocksize(basicblock *b) -{ - int i; - int size = 0; - - for (i = 0; i < b->b_iused; i++) - size += instrsize(b->b_instr[i].i_oparg); - return size; -} - -static int -assemble_emit_linetable_pair(struct assembler *a, int bdelta, int ldelta) -{ - Py_ssize_t len = PyBytes_GET_SIZE(a->a_lnotab); - if (a->a_lnotab_off + 2 >= len) { - if (_PyBytes_Resize(&a->a_lnotab, len * 2) < 0) - return 0; - } - unsigned char *lnotab = (unsigned char *) PyBytes_AS_STRING(a->a_lnotab); - lnotab += a->a_lnotab_off; - a->a_lnotab_off += 2; - *lnotab++ = bdelta; - *lnotab++ = ldelta; - return 1; -} - -/* Appends a range to the end of the line number table. See - * Objects/lnotab_notes.txt for the description of the line number table. */ - -static int -assemble_line_range(struct assembler *a) -{ - int ldelta, bdelta; - bdelta = (a->a_offset - a->a_lineno_start) * sizeof(_Py_CODEUNIT); - if (bdelta == 0) { - return 1; - } - if (a->a_lineno < 0) { - ldelta = -128; - } - else { - ldelta = a->a_lineno - a->a_prevlineno; - a->a_prevlineno = a->a_lineno; - while (ldelta > 127) { - if (!assemble_emit_linetable_pair(a, 0, 127)) { - return 0; - } - ldelta -= 127; - } - while (ldelta < -127) { - if (!assemble_emit_linetable_pair(a, 0, -127)) { - return 0; - } - ldelta += 127; - } - } - assert(-128 <= ldelta && ldelta < 128); - while (bdelta > 254) { - if (!assemble_emit_linetable_pair(a, 254, ldelta)) { - return 0; - } - ldelta = a->a_lineno < 0 ? -128 : 0; - bdelta -= 254; - } - if (!assemble_emit_linetable_pair(a, bdelta, ldelta)) { - return 0; - } - a->a_lineno_start = a->a_offset; - return 1; -} - -static int -assemble_lnotab(struct assembler *a, struct instr *i) -{ - if (i->i_lineno == a->a_lineno) { - return 1; - } - if (!assemble_line_range(a)) { - return 0; - } - a->a_lineno = i->i_lineno; - return 1; -} - - -/* assemble_emit() - Extend the bytecode with a new instruction. - Update lnotab if necessary. -*/ - -static int -assemble_emit(struct assembler *a, struct instr *i) -{ - int size, arg = 0; - Py_ssize_t len = PyBytes_GET_SIZE(a->a_bytecode); - _Py_CODEUNIT *code; - - arg = i->i_oparg; - size = instrsize(arg); - if (i->i_lineno && !assemble_lnotab(a, i)) - return 0; - if (a->a_offset + size >= len / (int)sizeof(_Py_CODEUNIT)) { - if (len > PY_SSIZE_T_MAX / 2) - return 0; - if (_PyBytes_Resize(&a->a_bytecode, len * 2) < 0) - return 0; - } - code = (_Py_CODEUNIT *)PyBytes_AS_STRING(a->a_bytecode) + a->a_offset; - a->a_offset += size; - write_op_arg(code, i->i_opcode, arg, size); - return 1; -} - -static void -normalize_jumps(struct assembler *a) -{ - for (basicblock *b = a->a_entry; b != NULL; b = b->b_next) { - b->b_visited = 0; - } - for (basicblock *b = a->a_entry; b != NULL; b = b->b_next) { - b->b_visited = 1; - if (b->b_iused == 0) { - continue; - } - struct instr *last = &b->b_instr[b->b_iused-1]; - if (last->i_opcode == JUMP_ABSOLUTE) { - if (last->i_target->b_visited == 0) { - last->i_opcode = JUMP_FORWARD; - } - } - if (last->i_opcode == JUMP_FORWARD) { - if (last->i_target->b_visited == 1) { - last->i_opcode = JUMP_ABSOLUTE; - } - } - } -} - -static void -assemble_jump_offsets(struct assembler *a, struct compiler *c) -{ - basicblock *b; - int bsize, totsize, extended_arg_recompile; - int i; - - /* Compute the size of each block and fixup jump args. - Replace block pointer with position in bytecode. */ - do { - totsize = 0; - for (basicblock *b = a->a_entry; b != NULL; b = b->b_next) { - bsize = blocksize(b); - b->b_offset = totsize; - totsize += bsize; - } - extended_arg_recompile = 0; - for (b = c->u->u_blocks; b != NULL; b = b->b_list) { - bsize = b->b_offset; - for (i = 0; i < b->b_iused; i++) { - struct instr *instr = &b->b_instr[i]; - int isize = instrsize(instr->i_oparg); - /* Relative jumps are computed relative to - the instruction pointer after fetching - the jump instruction. - */ - bsize += isize; - if (is_jump(instr)) { - instr->i_oparg = instr->i_target->b_offset; - if (is_relative_jump(instr)) { - instr->i_oparg -= bsize; - } - if (instrsize(instr->i_oparg) != isize) { - extended_arg_recompile = 1; - } - } - } - } - - /* XXX: This is an awful hack that could hurt performance, but - on the bright side it should work until we come up - with a better solution. - - The issue is that in the first loop blocksize() is called - which calls instrsize() which requires i_oparg be set - appropriately. There is a bootstrap problem because - i_oparg is calculated in the second loop above. - - So we loop until we stop seeing new EXTENDED_ARGs. - The only EXTENDED_ARGs that could be popping up are - ones in jump instructions. So this should converge - fairly quickly. - */ - } while (extended_arg_recompile); -} - -static PyObject * -dict_keys_inorder(PyObject *dict, Py_ssize_t offset) -{ - PyObject *tuple, *k, *v; - Py_ssize_t i, pos = 0, size = PyDict_GET_SIZE(dict); - - tuple = PyTuple_New(size); - if (tuple == NULL) - return NULL; - while (PyDict_Next(dict, &pos, &k, &v)) { - i = PyLong_AS_LONG(v); - Py_INCREF(k); - assert((i - offset) < size); - assert((i - offset) >= 0); - PyTuple_SET_ITEM(tuple, i - offset, k); - } - return tuple; -} - -static PyObject * -consts_dict_keys_inorder(PyObject *dict) -{ - PyObject *consts, *k, *v; - Py_ssize_t i, pos = 0, size = PyDict_GET_SIZE(dict); - - consts = PyList_New(size); /* PyCode_Optimize() requires a list */ - if (consts == NULL) - return NULL; - while (PyDict_Next(dict, &pos, &k, &v)) { - i = PyLong_AS_LONG(v); - /* The keys of the dictionary can be tuples wrapping a constant. - * (see compiler_add_o and _PyCode_ConstantKey). In that case - * the object we want is always second. */ - if (PyTuple_CheckExact(k)) { - k = PyTuple_GET_ITEM(k, 1); - } - Py_INCREF(k); - assert(i < size); - assert(i >= 0); - PyList_SET_ITEM(consts, i, k); - } - return consts; -} - -static int -compute_code_flags(struct compiler *c) -{ - PySTEntryObject *ste = c->u->u_ste; - int flags = 0; - if (ste->ste_type == FunctionBlock) { - flags |= CO_NEWLOCALS | CO_OPTIMIZED; - if (ste->ste_nested) - flags |= CO_NESTED; - if (ste->ste_generator && !ste->ste_coroutine) - flags |= CO_GENERATOR; - if (!ste->ste_generator && ste->ste_coroutine) - flags |= CO_COROUTINE; - if (ste->ste_generator && ste->ste_coroutine) - flags |= CO_ASYNC_GENERATOR; - if (ste->ste_varargs) - flags |= CO_VARARGS; - if (ste->ste_varkeywords) - flags |= CO_VARKEYWORDS; - } - - /* (Only) inherit compilerflags in PyCF_MASK */ - flags |= (c->c_flags->cf_flags & PyCF_MASK); - - if ((IS_TOP_LEVEL_AWAIT(c)) && - ste->ste_coroutine && - !ste->ste_generator) { - flags |= CO_COROUTINE; - } - - return flags; -} - -// Merge *obj* with constant cache. -// Unlike merge_consts_recursive(), this function doesn't work recursively. -static int -merge_const_one(struct compiler *c, PyObject **obj) -{ - PyObject *key = _PyCode_ConstantKey(*obj); - if (key == NULL) { - return 0; - } - - // t is borrowed reference - PyObject *t = PyDict_SetDefault(c->c_const_cache, key, key); - Py_DECREF(key); - if (t == NULL) { - return 0; - } - if (t == key) { // obj is new constant. - return 1; - } - - if (PyTuple_CheckExact(t)) { - // t is still borrowed reference - t = PyTuple_GET_ITEM(t, 1); - } - - Py_INCREF(t); - Py_DECREF(*obj); - *obj = t; - return 1; -} - -static PyCodeObject * -makecode(struct compiler *c, struct assembler *a, PyObject *consts) -{ - PyCodeObject *co = NULL; - PyObject *names = NULL; - PyObject *varnames = NULL; - PyObject *name = NULL; - PyObject *freevars = NULL; - PyObject *cellvars = NULL; - Py_ssize_t nlocals; - int nlocals_int; - int flags; - int posorkeywordargcount, posonlyargcount, kwonlyargcount, maxdepth; - - names = dict_keys_inorder(c->u->u_names, 0); - varnames = dict_keys_inorder(c->u->u_varnames, 0); - if (!names || !varnames) { - goto error; - } - cellvars = dict_keys_inorder(c->u->u_cellvars, 0); - if (!cellvars) - goto error; - freevars = dict_keys_inorder(c->u->u_freevars, PyTuple_GET_SIZE(cellvars)); - if (!freevars) - goto error; - - if (!merge_const_one(c, &names) || - !merge_const_one(c, &varnames) || - !merge_const_one(c, &cellvars) || - !merge_const_one(c, &freevars)) - { - goto error; - } - - nlocals = PyDict_GET_SIZE(c->u->u_varnames); - assert(nlocals < INT_MAX); - nlocals_int = Py_SAFE_DOWNCAST(nlocals, Py_ssize_t, int); - - flags = compute_code_flags(c); - if (flags < 0) - goto error; - - consts = PyList_AsTuple(consts); /* PyCode_New requires a tuple */ - if (consts == NULL) { - goto error; - } - if (!merge_const_one(c, &consts)) { - Py_DECREF(consts); - goto error; - } - - posonlyargcount = Py_SAFE_DOWNCAST(c->u->u_posonlyargcount, Py_ssize_t, int); - posorkeywordargcount = Py_SAFE_DOWNCAST(c->u->u_argcount, Py_ssize_t, int); - kwonlyargcount = Py_SAFE_DOWNCAST(c->u->u_kwonlyargcount, Py_ssize_t, int); - maxdepth = stackdepth(c); - if (maxdepth < 0) { - Py_DECREF(consts); - goto error; - } - if (maxdepth > MAX_ALLOWED_STACK_USE) { - PyErr_Format(PyExc_SystemError, - "excessive stack use: stack is %d deep", - maxdepth); - Py_DECREF(consts); - goto error; - } - co = PyCode_NewWithPosOnlyArgs(posonlyargcount+posorkeywordargcount, - posonlyargcount, kwonlyargcount, nlocals_int, - maxdepth, flags, a->a_bytecode, consts, names, - varnames, freevars, cellvars, c->c_filename, - c->u->u_name, c->u->u_firstlineno, a->a_lnotab); - Py_DECREF(consts); - error: - Py_XDECREF(names); - Py_XDECREF(varnames); - Py_XDECREF(name); - Py_XDECREF(freevars); - Py_XDECREF(cellvars); - return co; -} - - -/* For debugging purposes only */ -#if 0 -static void -dump_instr(struct instr *i) -{ - const char *jrel = (is_relative_jump(i)) ? "jrel " : ""; - const char *jabs = (is_jump(i) && !is_relative_jump(i))? "jabs " : ""; - - char arg[128]; - - *arg = '\0'; - if (HAS_ARG(i->i_opcode)) { - sprintf(arg, "arg: %d ", i->i_oparg); - } - fprintf(stderr, "line: %d, opcode: %d %s%s%s\n", - i->i_lineno, i->i_opcode, arg, jabs, jrel); -} - -static void -dump_basicblock(const basicblock *b) -{ - const char *b_return = b->b_return ? "return " : ""; - fprintf(stderr, "used: %d, depth: %d, offset: %d %s\n", - b->b_iused, b->b_startdepth, b->b_offset, b_return); - if (b->b_instr) { - int i; - for (i = 0; i < b->b_iused; i++) { - fprintf(stderr, " [%02d] ", i); - dump_instr(b->b_instr + i); - } - } -} -#endif - - -static int -normalize_basic_block(basicblock *bb); - -static int -optimize_cfg(struct compiler *c, struct assembler *a, PyObject *consts); - -static int -trim_unused_consts(struct compiler *c, struct assembler *a, PyObject *consts); - -/* Duplicates exit BBs, so that line numbers can be propagated to them */ -static int -duplicate_exits_without_lineno(struct compiler *c); - -static int -extend_block(basicblock *bb); - -static int -insert_generator_prefix(struct compiler *c, basicblock *entryblock) { - - int flags = compute_code_flags(c); - if (flags < 0) { - return -1; - } - int kind; - if (flags & (CO_GENERATOR | CO_COROUTINE | CO_ASYNC_GENERATOR)) { - if (flags & CO_COROUTINE) { - kind = 1; - } - else if (flags & CO_ASYNC_GENERATOR) { - kind = 2; - } - else { - kind = 0; - } - } - else { - return 0; - } - if (compiler_next_instr(entryblock) < 0) { - return -1; - } - for (int i = entryblock->b_iused-1; i > 0; i--) { - entryblock->b_instr[i] = entryblock->b_instr[i-1]; - } - entryblock->b_instr[0].i_opcode = GEN_START; - entryblock->b_instr[0].i_oparg = kind; - entryblock->b_instr[0].i_lineno = -1; - entryblock->b_instr[0].i_target = NULL; - return 0; -} - -/* Make sure that all returns have a line number, even if early passes - * have failed to propagate a correct line number. - * The resulting line number may not be correct according to PEP 626, - * but should be "good enough", and no worse than in older versions. */ -static void -guarantee_lineno_for_exits(struct assembler *a, int firstlineno) { - int lineno = firstlineno; - assert(lineno > 0); - for (basicblock *b = a->a_entry; b != NULL; b = b->b_next) { - if (b->b_iused == 0) { - continue; - } - struct instr *last = &b->b_instr[b->b_iused-1]; - if (last->i_lineno < 0) { - if (last->i_opcode == RETURN_VALUE) { - for (int i = 0; i < b->b_iused; i++) { - assert(b->b_instr[i].i_lineno < 0); - - b->b_instr[i].i_lineno = lineno; - } - } - } - else { - lineno = last->i_lineno; - } - } -} - -static void -propagate_line_numbers(struct assembler *a); - -static PyCodeObject * -assemble(struct compiler *c, int addNone) -{ - basicblock *b, *entryblock; - struct assembler a; - int j, nblocks; - PyCodeObject *co = NULL; - PyObject *consts = NULL; - - /* Make sure every block that falls off the end returns None. - XXX NEXT_BLOCK() isn't quite right, because if the last - block ends with a jump or return b_next shouldn't set. - */ - if (!c->u->u_curblock->b_return) { - c->u->u_lineno = -1; - if (addNone) - ADDOP_LOAD_CONST(c, Py_None); - ADDOP(c, RETURN_VALUE); - } - - for (basicblock *b = c->u->u_blocks; b != NULL; b = b->b_list) { - if (normalize_basic_block(b)) { - return NULL; - } - } - - for (basicblock *b = c->u->u_blocks; b != NULL; b = b->b_list) { - if (extend_block(b)) { - return NULL; - } - } - - nblocks = 0; - entryblock = NULL; - for (b = c->u->u_blocks; b != NULL; b = b->b_list) { - nblocks++; - entryblock = b; - } - assert(entryblock != NULL); - - if (insert_generator_prefix(c, entryblock)) { - goto error; - } - - /* Set firstlineno if it wasn't explicitly set. */ - if (!c->u->u_firstlineno) { - if (entryblock->b_instr && entryblock->b_instr->i_lineno) - c->u->u_firstlineno = entryblock->b_instr->i_lineno; - else - c->u->u_firstlineno = 1; - } - - if (!assemble_init(&a, nblocks, c->u->u_firstlineno)) - goto error; - a.a_entry = entryblock; - a.a_nblocks = nblocks; - - consts = consts_dict_keys_inorder(c->u->u_consts); - if (consts == NULL) { - goto error; - } - - if (optimize_cfg(c, &a, consts)) { - goto error; - } - if (duplicate_exits_without_lineno(c)) { - return NULL; - } - if (trim_unused_consts(c, &a, consts)) { - goto error; - } - propagate_line_numbers(&a); - guarantee_lineno_for_exits(&a, c->u->u_firstlineno); - - /* Order of basic blocks must have been determined by now */ - normalize_jumps(&a); - - /* Can't modify the bytecode after computing jump offsets. */ - assemble_jump_offsets(&a, c); - - /* Emit code. */ - for(b = entryblock; b != NULL; b = b->b_next) { - for (j = 0; j < b->b_iused; j++) - if (!assemble_emit(&a, &b->b_instr[j])) - goto error; - } - if (!assemble_line_range(&a)) { - return 0; - } - - if (_PyBytes_Resize(&a.a_lnotab, a.a_lnotab_off) < 0) { - goto error; - } - if (!merge_const_one(c, &a.a_lnotab)) { - goto error; - } - if (_PyBytes_Resize(&a.a_bytecode, a.a_offset * sizeof(_Py_CODEUNIT)) < 0) { - goto error; - } - if (!merge_const_one(c, &a.a_bytecode)) { - goto error; - } - - co = makecode(c, &a, consts); - error: - Py_XDECREF(consts); - assemble_free(&a); - return co; -} - -/* Replace LOAD_CONST c1, LOAD_CONST c2 ... LOAD_CONST cn, BUILD_TUPLE n - with LOAD_CONST (c1, c2, ... cn). - The consts table must still be in list form so that the - new constant (c1, c2, ... cn) can be appended. - Called with codestr pointing to the first LOAD_CONST. -*/ -static int -fold_tuple_on_constants(struct compiler *c, - struct instr *inst, - int n, PyObject *consts) -{ - /* Pre-conditions */ - assert(PyList_CheckExact(consts)); - assert(inst[n].i_opcode == BUILD_TUPLE); - assert(inst[n].i_oparg == n); - - for (int i = 0; i < n; i++) { - if (inst[i].i_opcode != LOAD_CONST) { - return 0; - } - } - - /* Buildup new tuple of constants */ - PyObject *newconst = PyTuple_New(n); - if (newconst == NULL) { - return -1; - } - for (int i = 0; i < n; i++) { - int arg = inst[i].i_oparg; - PyObject *constant = PyList_GET_ITEM(consts, arg); - Py_INCREF(constant); - PyTuple_SET_ITEM(newconst, i, constant); - } - if (merge_const_one(c, &newconst) == 0) { - Py_DECREF(newconst); - return -1; - } - - Py_ssize_t index; - for (index = 0; index < PyList_GET_SIZE(consts); index++) { - if (PyList_GET_ITEM(consts, index) == newconst) { - break; - } - } - if (index == PyList_GET_SIZE(consts)) { - if ((size_t)index >= (size_t)INT_MAX - 1) { - Py_DECREF(newconst); - PyErr_SetString(PyExc_OverflowError, "too many constants"); - return -1; - } - if (PyList_Append(consts, newconst)) { - Py_DECREF(newconst); - return -1; - } - } - Py_DECREF(newconst); - for (int i = 0; i < n; i++) { - inst[i].i_opcode = NOP; - } - inst[n].i_opcode = LOAD_CONST; - inst[n].i_oparg = (int)index; - return 0; -} - - -// Eliminate n * ROT_N(n). -static void -fold_rotations(struct instr *inst, int n) -{ - for (int i = 0; i < n; i++) { - int rot; - switch (inst[i].i_opcode) { - case ROT_N: - rot = inst[i].i_oparg; - break; - case ROT_FOUR: - rot = 4; - break; - case ROT_THREE: - rot = 3; - break; - case ROT_TWO: - rot = 2; - break; - default: - return; - } - if (rot != n) { - return; - } - } - for (int i = 0; i < n; i++) { - inst[i].i_opcode = NOP; - } -} - -// Attempt to eliminate jumps to jumps by updating inst to jump to -// target->i_target using the provided opcode. Return whether or not the -// optimization was successful. -static bool -jump_thread(struct instr *inst, struct instr *target, int opcode) -{ - assert(is_jump(inst)); - assert(is_jump(target)); - // bpo-45773: If inst->i_target == target->i_target, then nothing actually - // changes (and we fall into an infinite loop): - if (inst->i_lineno == target->i_lineno && - inst->i_target != target->i_target) - { - inst->i_target = target->i_target; - inst->i_opcode = opcode; - return true; - } - return false; -} - -/* Maximum size of basic block that should be copied in optimizer */ -#define MAX_COPY_SIZE 4 - -/* Optimization */ -static int -optimize_basic_block(struct compiler *c, basicblock *bb, PyObject *consts) -{ - assert(PyList_CheckExact(consts)); - struct instr nop; - nop.i_opcode = NOP; - struct instr *target; - for (int i = 0; i < bb->b_iused; i++) { - struct instr *inst = &bb->b_instr[i]; - int oparg = inst->i_oparg; - int nextop = i+1 < bb->b_iused ? bb->b_instr[i+1].i_opcode : 0; - if (is_jump(inst)) { - /* Skip over empty basic blocks. */ - while (inst->i_target->b_iused == 0) { - inst->i_target = inst->i_target->b_next; - } - target = &inst->i_target->b_instr[0]; - } - else { - target = &nop; - } - switch (inst->i_opcode) { - /* Remove LOAD_CONST const; conditional jump */ - case LOAD_CONST: - { - PyObject* cnt; - int is_true; - int jump_if_true; - switch(nextop) { - case POP_JUMP_IF_FALSE: - case POP_JUMP_IF_TRUE: - cnt = PyList_GET_ITEM(consts, oparg); - is_true = PyObject_IsTrue(cnt); - if (is_true == -1) { - goto error; - } - inst->i_opcode = NOP; - jump_if_true = nextop == POP_JUMP_IF_TRUE; - if (is_true == jump_if_true) { - bb->b_instr[i+1].i_opcode = JUMP_ABSOLUTE; - bb->b_nofallthrough = 1; - } - else { - bb->b_instr[i+1].i_opcode = NOP; - } - break; - case JUMP_IF_FALSE_OR_POP: - case JUMP_IF_TRUE_OR_POP: - cnt = PyList_GET_ITEM(consts, oparg); - is_true = PyObject_IsTrue(cnt); - if (is_true == -1) { - goto error; - } - jump_if_true = nextop == JUMP_IF_TRUE_OR_POP; - if (is_true == jump_if_true) { - bb->b_instr[i+1].i_opcode = JUMP_ABSOLUTE; - bb->b_nofallthrough = 1; - } - else { - inst->i_opcode = NOP; - bb->b_instr[i+1].i_opcode = NOP; - } - break; - } - break; - } - - /* Try to fold tuples of constants. - Skip over BUILD_SEQN 1 UNPACK_SEQN 1. - Replace BUILD_SEQN 2 UNPACK_SEQN 2 with ROT2. - Replace BUILD_SEQN 3 UNPACK_SEQN 3 with ROT3 ROT2. */ - case BUILD_TUPLE: - if (nextop == UNPACK_SEQUENCE && oparg == bb->b_instr[i+1].i_oparg) { - switch(oparg) { - case 1: - inst->i_opcode = NOP; - bb->b_instr[i+1].i_opcode = NOP; - break; - case 2: - inst->i_opcode = ROT_TWO; - bb->b_instr[i+1].i_opcode = NOP; - break; - case 3: - inst->i_opcode = ROT_THREE; - bb->b_instr[i+1].i_opcode = ROT_TWO; - } - break; - } - if (i >= oparg) { - if (fold_tuple_on_constants(c, inst-oparg, oparg, consts)) { - goto error; - } - } - break; - - /* Simplify conditional jump to conditional jump where the - result of the first test implies the success of a similar - test or the failure of the opposite test. - Arises in code like: - "a and b or c" - "(a and b) and c" - "(a or b) or c" - "(a or b) and c" - x:JUMP_IF_FALSE_OR_POP y y:JUMP_IF_FALSE_OR_POP z - --> x:JUMP_IF_FALSE_OR_POP z - x:JUMP_IF_FALSE_OR_POP y y:JUMP_IF_TRUE_OR_POP z - --> x:POP_JUMP_IF_FALSE y+1 - where y+1 is the instruction following the second test. - */ - case JUMP_IF_FALSE_OR_POP: - switch (target->i_opcode) { - case POP_JUMP_IF_FALSE: - i -= jump_thread(inst, target, POP_JUMP_IF_FALSE); - break; - case JUMP_ABSOLUTE: - case JUMP_FORWARD: - case JUMP_IF_FALSE_OR_POP: - i -= jump_thread(inst, target, JUMP_IF_FALSE_OR_POP); - break; - case JUMP_IF_TRUE_OR_POP: - case POP_JUMP_IF_TRUE: - if (inst->i_lineno == target->i_lineno) { - // We don't need to bother checking for loops here, - // since a block's b_next cannot point to itself: - assert(inst->i_target != inst->i_target->b_next); - inst->i_opcode = POP_JUMP_IF_FALSE; - inst->i_target = inst->i_target->b_next; - --i; - } - break; - } - break; - case JUMP_IF_TRUE_OR_POP: - switch (target->i_opcode) { - case POP_JUMP_IF_TRUE: - i -= jump_thread(inst, target, POP_JUMP_IF_TRUE); - break; - case JUMP_ABSOLUTE: - case JUMP_FORWARD: - case JUMP_IF_TRUE_OR_POP: - i -= jump_thread(inst, target, JUMP_IF_TRUE_OR_POP); - break; - case JUMP_IF_FALSE_OR_POP: - case POP_JUMP_IF_FALSE: - if (inst->i_lineno == target->i_lineno) { - // We don't need to bother checking for loops here, - // since a block's b_next cannot point to itself: - assert(inst->i_target != inst->i_target->b_next); - inst->i_opcode = POP_JUMP_IF_TRUE; - inst->i_target = inst->i_target->b_next; - --i; - } - break; - } - break; - case POP_JUMP_IF_FALSE: - switch (target->i_opcode) { - case JUMP_ABSOLUTE: - case JUMP_FORWARD: - i -= jump_thread(inst, target, POP_JUMP_IF_FALSE); - } - break; - case POP_JUMP_IF_TRUE: - switch (target->i_opcode) { - case JUMP_ABSOLUTE: - case JUMP_FORWARD: - i -= jump_thread(inst, target, POP_JUMP_IF_TRUE); - } - break; - case JUMP_ABSOLUTE: - case JUMP_FORWARD: - switch (target->i_opcode) { - case JUMP_ABSOLUTE: - case JUMP_FORWARD: - i -= jump_thread(inst, target, JUMP_ABSOLUTE); - } - break; - case FOR_ITER: - if (target->i_opcode == JUMP_FORWARD) { - i -= jump_thread(inst, target, FOR_ITER); - } - break; - case ROT_N: - switch (oparg) { - case 0: - case 1: - inst->i_opcode = NOP; - continue; - case 2: - inst->i_opcode = ROT_TWO; - break; - case 3: - inst->i_opcode = ROT_THREE; - break; - case 4: - inst->i_opcode = ROT_FOUR; - break; - } - if (i >= oparg - 1) { - fold_rotations(inst - oparg + 1, oparg); - } - break; - } - } - return 0; -error: - return -1; -} - -/* If this block ends with an unconditional jump to an exit block, - * then remove the jump and extend this block with the target. - */ -static int -extend_block(basicblock *bb) { - if (bb->b_iused == 0) { - return 0; - } - struct instr *last = &bb->b_instr[bb->b_iused-1]; - if (last->i_opcode != JUMP_ABSOLUTE && last->i_opcode != JUMP_FORWARD) { - return 0; - } - if (last->i_target->b_exit && last->i_target->b_iused <= MAX_COPY_SIZE) { - basicblock *to_copy = last->i_target; - last->i_opcode = NOP; - for (int i = 0; i < to_copy->b_iused; i++) { - int index = compiler_next_instr(bb); - if (index < 0) { - return -1; - } - bb->b_instr[index] = to_copy->b_instr[i]; - } - bb->b_exit = 1; - } - return 0; -} - -static void -clean_basic_block(basicblock *bb, int prev_lineno) { - /* Remove NOPs when legal to do so. */ - int dest = 0; - for (int src = 0; src < bb->b_iused; src++) { - int lineno = bb->b_instr[src].i_lineno; - if (bb->b_instr[src].i_opcode == NOP) { - /* Eliminate no-op if it doesn't have a line number */ - if (lineno < 0) { - continue; - } - /* or, if the previous instruction had the same line number. */ - if (prev_lineno == lineno) { - continue; - } - /* or, if the next instruction has same line number or no line number */ - if (src < bb->b_iused - 1) { - int next_lineno = bb->b_instr[src+1].i_lineno; - if (next_lineno < 0 || next_lineno == lineno) { - bb->b_instr[src+1].i_lineno = lineno; - continue; - } - } - else { - basicblock* next = bb->b_next; - while (next && next->b_iused == 0) { - next = next->b_next; - } - /* or if last instruction in BB and next BB has same line number */ - if (next) { - if (lineno == next->b_instr[0].i_lineno) { - continue; - } - } - } - - } - if (dest != src) { - bb->b_instr[dest] = bb->b_instr[src]; - } - dest++; - prev_lineno = lineno; - } - assert(dest <= bb->b_iused); - bb->b_iused = dest; -} - -static int -normalize_basic_block(basicblock *bb) { - /* Mark blocks as exit and/or nofallthrough. - Raise SystemError if CFG is malformed. */ - for (int i = 0; i < bb->b_iused; i++) { - switch(bb->b_instr[i].i_opcode) { - case RETURN_VALUE: - case RAISE_VARARGS: - case RERAISE: - bb->b_exit = 1; - bb->b_nofallthrough = 1; - break; - case JUMP_ABSOLUTE: - case JUMP_FORWARD: - bb->b_nofallthrough = 1; - /* fall through */ - case POP_JUMP_IF_FALSE: - case POP_JUMP_IF_TRUE: - case JUMP_IF_FALSE_OR_POP: - case JUMP_IF_TRUE_OR_POP: - case FOR_ITER: - if (i != bb->b_iused-1) { - PyErr_SetString(PyExc_SystemError, "malformed control flow graph."); - return -1; - } - /* Skip over empty basic blocks. */ - while (bb->b_instr[i].i_target->b_iused == 0) { - bb->b_instr[i].i_target = bb->b_instr[i].i_target->b_next; - } - - } - } - return 0; -} - -static int -mark_reachable(struct assembler *a) { - basicblock **stack, **sp; - sp = stack = (basicblock **)PyObject_Malloc(sizeof(basicblock *) * a->a_nblocks); - if (stack == NULL) { - return -1; - } - a->a_entry->b_predecessors = 1; - *sp++ = a->a_entry; - while (sp > stack) { - basicblock *b = *(--sp); - if (b->b_next && !b->b_nofallthrough) { - if (b->b_next->b_predecessors == 0) { - *sp++ = b->b_next; - } - b->b_next->b_predecessors++; - } - for (int i = 0; i < b->b_iused; i++) { - basicblock *target; - if (is_jump(&b->b_instr[i])) { - target = b->b_instr[i].i_target; - if (target->b_predecessors == 0) { - *sp++ = target; - } - target->b_predecessors++; - } - } - } - PyObject_Free(stack); - return 0; -} - -static void -eliminate_empty_basic_blocks(basicblock *entry) { - /* Eliminate empty blocks */ - for (basicblock *b = entry; b != NULL; b = b->b_next) { - basicblock *next = b->b_next; - if (next) { - while (next->b_iused == 0 && next->b_next) { - next = next->b_next; - } - b->b_next = next; - } - } - for (basicblock *b = entry; b != NULL; b = b->b_next) { - if (b->b_iused == 0) { - continue; - } - if (is_jump(&b->b_instr[b->b_iused-1])) { - basicblock *target = b->b_instr[b->b_iused-1].i_target; - while (target->b_iused == 0) { - target = target->b_next; - } - b->b_instr[b->b_iused-1].i_target = target; - } - } -} - - -/* If an instruction has no line number, but it's predecessor in the BB does, - * then copy the line number. If a successor block has no line number, and only - * one predecessor, then inherit the line number. - * This ensures that all exit blocks (with one predecessor) receive a line number. - * Also reduces the size of the line number table, - * but has no impact on the generated line number events. - */ -static void -propagate_line_numbers(struct assembler *a) { - for (basicblock *b = a->a_entry; b != NULL; b = b->b_next) { - if (b->b_iused == 0) { - continue; - } - int prev_lineno = -1; - for (int i = 0; i < b->b_iused; i++) { - if (b->b_instr[i].i_lineno < 0) { - b->b_instr[i].i_lineno = prev_lineno; - } - else { - prev_lineno = b->b_instr[i].i_lineno; - } - } - if (!b->b_nofallthrough && b->b_next->b_predecessors == 1) { - assert(b->b_next->b_iused); - if (b->b_next->b_instr[0].i_lineno < 0) { - b->b_next->b_instr[0].i_lineno = prev_lineno; - } - } - if (is_jump(&b->b_instr[b->b_iused-1])) { - switch (b->b_instr[b->b_iused-1].i_opcode) { - /* Note: Only actual jumps, not exception handlers */ - case SETUP_ASYNC_WITH: - case SETUP_WITH: - case SETUP_FINALLY: - continue; - } - basicblock *target = b->b_instr[b->b_iused-1].i_target; - if (target->b_predecessors == 1) { - if (target->b_instr[0].i_lineno < 0) { - target->b_instr[0].i_lineno = prev_lineno; - } - } - } - } -} - -/* Perform optimizations on a control flow graph. - The consts object should still be in list form to allow new constants - to be appended. - - All transformations keep the code size the same or smaller. - For those that reduce size, the gaps are initially filled with - NOPs. Later those NOPs are removed. -*/ - -static int -optimize_cfg(struct compiler *c, struct assembler *a, PyObject *consts) -{ - for (basicblock *b = a->a_entry; b != NULL; b = b->b_next) { - if (optimize_basic_block(c, b, consts)) { - return -1; - } - clean_basic_block(b, -1); - assert(b->b_predecessors == 0); - } - for (basicblock *b = c->u->u_blocks; b != NULL; b = b->b_list) { - if (extend_block(b)) { - return -1; - } - } - if (mark_reachable(a)) { - return -1; - } - /* Delete unreachable instructions */ - for (basicblock *b = a->a_entry; b != NULL; b = b->b_next) { - if (b->b_predecessors == 0) { - b->b_iused = 0; - b->b_nofallthrough = 0; - } - } - basicblock *pred = NULL; - for (basicblock *b = a->a_entry; b != NULL; b = b->b_next) { - int prev_lineno = -1; - if (pred && pred->b_iused) { - prev_lineno = pred->b_instr[pred->b_iused-1].i_lineno; - } - clean_basic_block(b, prev_lineno); - pred = b->b_nofallthrough ? NULL : b; - } - eliminate_empty_basic_blocks(a->a_entry); - /* Delete jump instructions made redundant by previous step. If a non-empty - block ends with a jump instruction, check if the next non-empty block - reached through normal flow control is the target of that jump. If it - is, then the jump instruction is redundant and can be deleted. - */ - int maybe_empty_blocks = 0; - for (basicblock *b = a->a_entry; b != NULL; b = b->b_next) { - if (b->b_iused > 0) { - struct instr *b_last_instr = &b->b_instr[b->b_iused - 1]; - if (b_last_instr->i_opcode == JUMP_ABSOLUTE || - b_last_instr->i_opcode == JUMP_FORWARD) { - if (b_last_instr->i_target == b->b_next) { - assert(b->b_next->b_iused); - b->b_nofallthrough = 0; - b_last_instr->i_opcode = NOP; - clean_basic_block(b, -1); - maybe_empty_blocks = 1; - } - } - } - } - if (maybe_empty_blocks) { - eliminate_empty_basic_blocks(a->a_entry); - } - return 0; -} - -// Remove trailing unused constants. -static int -trim_unused_consts(struct compiler *c, struct assembler *a, PyObject *consts) -{ - assert(PyList_CheckExact(consts)); - - // The first constant may be docstring; keep it always. - int max_const_index = 0; - for (basicblock *b = a->a_entry; b != NULL; b = b->b_next) { - for (int i = 0; i < b->b_iused; i++) { - if (b->b_instr[i].i_opcode == LOAD_CONST && - b->b_instr[i].i_oparg > max_const_index) { - max_const_index = b->b_instr[i].i_oparg; - } - } - } - if (max_const_index+1 < PyList_GET_SIZE(consts)) { - //fprintf(stderr, "removing trailing consts: max=%d, size=%d\n", - // max_const_index, (int)PyList_GET_SIZE(consts)); - if (PyList_SetSlice(consts, max_const_index+1, - PyList_GET_SIZE(consts), NULL) < 0) { - return 1; - } - } - return 0; -} - -static inline int -is_exit_without_lineno(basicblock *b) { - return b->b_exit && b->b_instr[0].i_lineno < 0; -} - -/* PEP 626 mandates that the f_lineno of a frame is correct - * after a frame terminates. It would be prohibitively expensive - * to continuously update the f_lineno field at runtime, - * so we make sure that all exiting instruction (raises and returns) - * have a valid line number, allowing us to compute f_lineno lazily. - * We can do this by duplicating the exit blocks without line number - * so that none have more than one predecessor. We can then safely - * copy the line number from the sole predecessor block. - */ -static int -duplicate_exits_without_lineno(struct compiler *c) -{ - /* Copy all exit blocks without line number that are targets of a jump. - */ - for (basicblock *b = c->u->u_blocks; b != NULL; b = b->b_list) { - if (b->b_iused > 0 && is_jump(&b->b_instr[b->b_iused-1])) { - switch (b->b_instr[b->b_iused-1].i_opcode) { - /* Note: Only actual jumps, not exception handlers */ - case SETUP_ASYNC_WITH: - case SETUP_WITH: - case SETUP_FINALLY: - continue; - } - basicblock *target = b->b_instr[b->b_iused-1].i_target; - if (is_exit_without_lineno(target) && target->b_predecessors > 1) { - basicblock *new_target = compiler_copy_block(c, target); - if (new_target == NULL) { - return -1; - } - new_target->b_instr[0].i_lineno = b->b_instr[b->b_iused-1].i_lineno; - b->b_instr[b->b_iused-1].i_target = new_target; - target->b_predecessors--; - new_target->b_predecessors = 1; - new_target->b_next = target->b_next; - target->b_next = new_target; - } - } - } - /* Eliminate empty blocks */ - for (basicblock *b = c->u->u_blocks; b != NULL; b = b->b_list) { - while (b->b_next && b->b_next->b_iused == 0) { - b->b_next = b->b_next->b_next; - } - } - /* Any remaining reachable exit blocks without line number can only be reached by - * fall through, and thus can only have a single predecessor */ - for (basicblock *b = c->u->u_blocks; b != NULL; b = b->b_list) { - if (!b->b_nofallthrough && b->b_next && b->b_iused > 0) { - if (is_exit_without_lineno(b->b_next)) { - assert(b->b_next->b_iused > 0); - b->b_next->b_instr[0].i_lineno = b->b_instr[b->b_iused-1].i_lineno; - } - } - } - return 0; -} - - -/* Retained for API compatibility. - * Optimization is now done in optimize_cfg */ - -PyObject * -PyCode_Optimize(PyObject *code, PyObject* Py_UNUSED(consts), - PyObject *Py_UNUSED(names), PyObject *Py_UNUSED(lnotab_obj)) -{ - Py_INCREF(code); - return code; -} diff --git a/contrib/tools/python3/src/Python/condvar.h b/contrib/tools/python3/src/Python/condvar.h deleted file mode 100644 index e5df7ff1328..00000000000 --- a/contrib/tools/python3/src/Python/condvar.h +++ /dev/null @@ -1,309 +0,0 @@ -/* - * Portable condition variable support for windows and pthreads. - * Everything is inline, this header can be included where needed. - * - * APIs generally return 0 on success and non-zero on error, - * and the caller needs to use its platform's error mechanism to - * discover the error (errno, or GetLastError()) - * - * Note that some implementations cannot distinguish between a - * condition variable wait time-out and successful wait. Most often - * the difference is moot anyway since the wait condition must be - * re-checked. - * PyCOND_TIMEDWAIT, in addition to returning negative on error, - * thus returns 0 on regular success, 1 on timeout - * or 2 if it can't tell. - * - * There are at least two caveats with using these condition variables, - * due to the fact that they may be emulated with Semaphores on - * Windows: - * 1) While PyCOND_SIGNAL() will wake up at least one thread, we - * cannot currently guarantee that it will be one of the threads - * already waiting in a PyCOND_WAIT() call. It _could_ cause - * the wakeup of a subsequent thread to try a PyCOND_WAIT(), - * including the thread doing the PyCOND_SIGNAL() itself. - * The same applies to PyCOND_BROADCAST(), if N threads are waiting - * then at least N threads will be woken up, but not necessarily - * those already waiting. - * For this reason, don't make the scheduling assumption that a - * specific other thread will get the wakeup signal - * 2) The _mutex_ must be held when calling PyCOND_SIGNAL() and - * PyCOND_BROADCAST(). - * While e.g. the posix standard strongly recommends that the mutex - * associated with the condition variable is held when a - * pthread_cond_signal() call is made, this is not a hard requirement, - * although scheduling will not be "reliable" if it isn't. Here - * the mutex is used for internal synchronization of the emulated - * Condition Variable. - */ - -#ifndef _CONDVAR_IMPL_H_ -#define _CONDVAR_IMPL_H_ - -#include "Python.h" -#include "pycore_condvar.h" - -#ifdef _POSIX_THREADS -/* - * POSIX support - */ - -/* These private functions are implemented in Python/thread_pthread.h */ -int _PyThread_cond_init(PyCOND_T *cond); -void _PyThread_cond_after(long long us, struct timespec *abs); - -/* The following functions return 0 on success, nonzero on error */ -#define PyMUTEX_INIT(mut) pthread_mutex_init((mut), NULL) -#define PyMUTEX_FINI(mut) pthread_mutex_destroy(mut) -#define PyMUTEX_LOCK(mut) pthread_mutex_lock(mut) -#define PyMUTEX_UNLOCK(mut) pthread_mutex_unlock(mut) - -#define PyCOND_INIT(cond) _PyThread_cond_init(cond) -#define PyCOND_FINI(cond) pthread_cond_destroy(cond) -#define PyCOND_SIGNAL(cond) pthread_cond_signal(cond) -#define PyCOND_BROADCAST(cond) pthread_cond_broadcast(cond) -#define PyCOND_WAIT(cond, mut) pthread_cond_wait((cond), (mut)) - -/* return 0 for success, 1 on timeout, -1 on error */ -Py_LOCAL_INLINE(int) -PyCOND_TIMEDWAIT(PyCOND_T *cond, PyMUTEX_T *mut, long long us) -{ - struct timespec abs; - _PyThread_cond_after(us, &abs); - int ret = pthread_cond_timedwait(cond, mut, &abs); - if (ret == ETIMEDOUT) { - return 1; - } - if (ret) { - return -1; - } - return 0; -} - -#elif defined(NT_THREADS) -/* - * Windows (XP, 2003 server and later, as well as (hopefully) CE) support - * - * Emulated condition variables ones that work with XP and later, plus - * example native support on VISTA and onwards. - */ - -#if _PY_EMULATED_WIN_CV - -/* The mutex is a CriticalSection object and - The condition variables is emulated with the help of a semaphore. - - This implementation still has the problem that the threads woken - with a "signal" aren't necessarily those that are already - waiting. It corresponds to listing 2 in: - http://birrell.org/andrew/papers/ImplementingCVs.pdf - - Generic emulations of the pthread_cond_* API using - earlier Win32 functions can be found on the web. - The following read can be give background information to these issues, - but the implementations are all broken in some way. - http://www.cse.wustl.edu/~schmidt/win32-cv-1.html -*/ - -Py_LOCAL_INLINE(int) -PyMUTEX_INIT(PyMUTEX_T *cs) -{ - InitializeCriticalSection(cs); - return 0; -} - -Py_LOCAL_INLINE(int) -PyMUTEX_FINI(PyMUTEX_T *cs) -{ - DeleteCriticalSection(cs); - return 0; -} - -Py_LOCAL_INLINE(int) -PyMUTEX_LOCK(PyMUTEX_T *cs) -{ - EnterCriticalSection(cs); - return 0; -} - -Py_LOCAL_INLINE(int) -PyMUTEX_UNLOCK(PyMUTEX_T *cs) -{ - LeaveCriticalSection(cs); - return 0; -} - - -Py_LOCAL_INLINE(int) -PyCOND_INIT(PyCOND_T *cv) -{ - /* A semaphore with a "large" max value, The positive value - * is only needed to catch those "lost wakeup" events and - * race conditions when a timed wait elapses. - */ - cv->sem = CreateSemaphore(NULL, 0, 100000, NULL); - if (cv->sem==NULL) - return -1; - cv->waiting = 0; - return 0; -} - -Py_LOCAL_INLINE(int) -PyCOND_FINI(PyCOND_T *cv) -{ - return CloseHandle(cv->sem) ? 0 : -1; -} - -/* this implementation can detect a timeout. Returns 1 on timeout, - * 0 otherwise (and -1 on error) - */ -Py_LOCAL_INLINE(int) -_PyCOND_WAIT_MS(PyCOND_T *cv, PyMUTEX_T *cs, DWORD ms) -{ - DWORD wait; - cv->waiting++; - PyMUTEX_UNLOCK(cs); - /* "lost wakeup bug" would occur if the caller were interrupted here, - * but we are safe because we are using a semaphore which has an internal - * count. - */ - wait = WaitForSingleObjectEx(cv->sem, ms, FALSE); - PyMUTEX_LOCK(cs); - if (wait != WAIT_OBJECT_0) - --cv->waiting; - /* Here we have a benign race condition with PyCOND_SIGNAL. - * When failure occurs or timeout, it is possible that - * PyCOND_SIGNAL also decrements this value - * and signals releases the mutex. This is benign because it - * just means an extra spurious wakeup for a waiting thread. - * ('waiting' corresponds to the semaphore's "negative" count and - * we may end up with e.g. (waiting == -1 && sem.count == 1). When - * a new thread comes along, it will pass right through, having - * adjusted it to (waiting == 0 && sem.count == 0). - */ - - if (wait == WAIT_FAILED) - return -1; - /* return 0 on success, 1 on timeout */ - return wait != WAIT_OBJECT_0; -} - -Py_LOCAL_INLINE(int) -PyCOND_WAIT(PyCOND_T *cv, PyMUTEX_T *cs) -{ - int result = _PyCOND_WAIT_MS(cv, cs, INFINITE); - return result >= 0 ? 0 : result; -} - -Py_LOCAL_INLINE(int) -PyCOND_TIMEDWAIT(PyCOND_T *cv, PyMUTEX_T *cs, long long us) -{ - return _PyCOND_WAIT_MS(cv, cs, (DWORD)(us/1000)); -} - -Py_LOCAL_INLINE(int) -PyCOND_SIGNAL(PyCOND_T *cv) -{ - /* this test allows PyCOND_SIGNAL to be a no-op unless required - * to wake someone up, thus preventing an unbounded increase of - * the semaphore's internal counter. - */ - if (cv->waiting > 0) { - /* notifying thread decreases the cv->waiting count so that - * a delay between notify and actual wakeup of the target thread - * doesn't cause a number of extra ReleaseSemaphore calls. - */ - cv->waiting--; - return ReleaseSemaphore(cv->sem, 1, NULL) ? 0 : -1; - } - return 0; -} - -Py_LOCAL_INLINE(int) -PyCOND_BROADCAST(PyCOND_T *cv) -{ - int waiting = cv->waiting; - if (waiting > 0) { - cv->waiting = 0; - return ReleaseSemaphore(cv->sem, waiting, NULL) ? 0 : -1; - } - return 0; -} - -#else /* !_PY_EMULATED_WIN_CV */ - -Py_LOCAL_INLINE(int) -PyMUTEX_INIT(PyMUTEX_T *cs) -{ - InitializeSRWLock(cs); - return 0; -} - -Py_LOCAL_INLINE(int) -PyMUTEX_FINI(PyMUTEX_T *cs) -{ - return 0; -} - -Py_LOCAL_INLINE(int) -PyMUTEX_LOCK(PyMUTEX_T *cs) -{ - AcquireSRWLockExclusive(cs); - return 0; -} - -Py_LOCAL_INLINE(int) -PyMUTEX_UNLOCK(PyMUTEX_T *cs) -{ - ReleaseSRWLockExclusive(cs); - return 0; -} - - -Py_LOCAL_INLINE(int) -PyCOND_INIT(PyCOND_T *cv) -{ - InitializeConditionVariable(cv); - return 0; -} -Py_LOCAL_INLINE(int) -PyCOND_FINI(PyCOND_T *cv) -{ - return 0; -} - -Py_LOCAL_INLINE(int) -PyCOND_WAIT(PyCOND_T *cv, PyMUTEX_T *cs) -{ - return SleepConditionVariableSRW(cv, cs, INFINITE, 0) ? 0 : -1; -} - -/* This implementation makes no distinction about timeouts. Signal - * 2 to indicate that we don't know. - */ -Py_LOCAL_INLINE(int) -PyCOND_TIMEDWAIT(PyCOND_T *cv, PyMUTEX_T *cs, long long us) -{ - return SleepConditionVariableSRW(cv, cs, (DWORD)(us/1000), 0) ? 2 : -1; -} - -Py_LOCAL_INLINE(int) -PyCOND_SIGNAL(PyCOND_T *cv) -{ - WakeConditionVariable(cv); - return 0; -} - -Py_LOCAL_INLINE(int) -PyCOND_BROADCAST(PyCOND_T *cv) -{ - WakeAllConditionVariable(cv); - return 0; -} - - -#endif /* _PY_EMULATED_WIN_CV */ - -#endif /* _POSIX_THREADS, NT_THREADS */ - -#endif /* _CONDVAR_IMPL_H_ */ diff --git a/contrib/tools/python3/src/Python/context.c b/contrib/tools/python3/src/Python/context.c deleted file mode 100644 index bf2ba93c14e..00000000000 --- a/contrib/tools/python3/src/Python/context.c +++ /dev/null @@ -1,1342 +0,0 @@ -#include "Python.h" - -#include "pycore_context.h" -#include "pycore_gc.h" // _PyObject_GC_MAY_BE_TRACKED() -#include "pycore_hamt.h" -#include "pycore_object.h" -#include "pycore_pyerrors.h" -#include "pycore_pystate.h" // _PyThreadState_GET() -#include "structmember.h" // PyMemberDef - - -#define CONTEXT_FREELIST_MAXLEN 255 - - -#include "clinic/context.c.h" -/*[clinic input] -module _contextvars -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=a0955718c8b8cea6]*/ - - -#define ENSURE_Context(o, err_ret) \ - if (!PyContext_CheckExact(o)) { \ - PyErr_SetString(PyExc_TypeError, \ - "an instance of Context was expected"); \ - return err_ret; \ - } - -#define ENSURE_ContextVar(o, err_ret) \ - if (!PyContextVar_CheckExact(o)) { \ - PyErr_SetString(PyExc_TypeError, \ - "an instance of ContextVar was expected"); \ - return err_ret; \ - } - -#define ENSURE_ContextToken(o, err_ret) \ - if (!PyContextToken_CheckExact(o)) { \ - PyErr_SetString(PyExc_TypeError, \ - "an instance of Token was expected"); \ - return err_ret; \ - } - - -/////////////////////////// Context API - - -static PyContext * -context_new_empty(void); - -static PyContext * -context_new_from_vars(PyHamtObject *vars); - -static inline PyContext * -context_get(void); - -static PyContextToken * -token_new(PyContext *ctx, PyContextVar *var, PyObject *val); - -static PyContextVar * -contextvar_new(PyObject *name, PyObject *def); - -static int -contextvar_set(PyContextVar *var, PyObject *val); - -static int -contextvar_del(PyContextVar *var); - - -static struct _Py_context_state * -get_context_state(void) -{ - PyInterpreterState *interp = _PyInterpreterState_GET(); - return &interp->context; -} - - -PyObject * -_PyContext_NewHamtForTests(void) -{ - return (PyObject *)_PyHamt_New(); -} - - -PyObject * -PyContext_New(void) -{ - return (PyObject *)context_new_empty(); -} - - -PyObject * -PyContext_Copy(PyObject * octx) -{ - ENSURE_Context(octx, NULL) - PyContext *ctx = (PyContext *)octx; - return (PyObject *)context_new_from_vars(ctx->ctx_vars); -} - - -PyObject * -PyContext_CopyCurrent(void) -{ - PyContext *ctx = context_get(); - if (ctx == NULL) { - return NULL; - } - - return (PyObject *)context_new_from_vars(ctx->ctx_vars); -} - - -static int -_PyContext_Enter(PyThreadState *ts, PyObject *octx) -{ - ENSURE_Context(octx, -1) - PyContext *ctx = (PyContext *)octx; - - if (ctx->ctx_entered) { - _PyErr_Format(ts, PyExc_RuntimeError, - "cannot enter context: %R is already entered", ctx); - return -1; - } - - ctx->ctx_prev = (PyContext *)ts->context; /* borrow */ - ctx->ctx_entered = 1; - - Py_INCREF(ctx); - ts->context = (PyObject *)ctx; - ts->context_ver++; - - return 0; -} - - -int -PyContext_Enter(PyObject *octx) -{ - PyThreadState *ts = _PyThreadState_GET(); - assert(ts != NULL); - return _PyContext_Enter(ts, octx); -} - - -static int -_PyContext_Exit(PyThreadState *ts, PyObject *octx) -{ - ENSURE_Context(octx, -1) - PyContext *ctx = (PyContext *)octx; - - if (!ctx->ctx_entered) { - PyErr_Format(PyExc_RuntimeError, - "cannot exit context: %R has not been entered", ctx); - return -1; - } - - if (ts->context != (PyObject *)ctx) { - /* Can only happen if someone misuses the C API */ - PyErr_SetString(PyExc_RuntimeError, - "cannot exit context: thread state references " - "a different context object"); - return -1; - } - - Py_SETREF(ts->context, (PyObject *)ctx->ctx_prev); - ts->context_ver++; - - ctx->ctx_prev = NULL; - ctx->ctx_entered = 0; - - return 0; -} - -int -PyContext_Exit(PyObject *octx) -{ - PyThreadState *ts = _PyThreadState_GET(); - assert(ts != NULL); - return _PyContext_Exit(ts, octx); -} - - -PyObject * -PyContextVar_New(const char *name, PyObject *def) -{ - PyObject *pyname = PyUnicode_FromString(name); - if (pyname == NULL) { - return NULL; - } - PyContextVar *var = contextvar_new(pyname, def); - Py_DECREF(pyname); - return (PyObject *)var; -} - - -int -PyContextVar_Get(PyObject *ovar, PyObject *def, PyObject **val) -{ - ENSURE_ContextVar(ovar, -1) - PyContextVar *var = (PyContextVar *)ovar; - - PyThreadState *ts = _PyThreadState_GET(); - assert(ts != NULL); - if (ts->context == NULL) { - goto not_found; - } - - if (var->var_cached != NULL && - var->var_cached_tsid == ts->id && - var->var_cached_tsver == ts->context_ver) - { - *val = var->var_cached; - goto found; - } - - assert(PyContext_CheckExact(ts->context)); - PyHamtObject *vars = ((PyContext *)ts->context)->ctx_vars; - - PyObject *found = NULL; - int res = _PyHamt_Find(vars, (PyObject*)var, &found); - if (res < 0) { - goto error; - } - if (res == 1) { - assert(found != NULL); - var->var_cached = found; /* borrow */ - var->var_cached_tsid = ts->id; - var->var_cached_tsver = ts->context_ver; - - *val = found; - goto found; - } - -not_found: - if (def == NULL) { - if (var->var_default != NULL) { - *val = var->var_default; - goto found; - } - - *val = NULL; - goto found; - } - else { - *val = def; - goto found; - } - -found: - Py_XINCREF(*val); - return 0; - -error: - *val = NULL; - return -1; -} - - -PyObject * -PyContextVar_Set(PyObject *ovar, PyObject *val) -{ - ENSURE_ContextVar(ovar, NULL) - PyContextVar *var = (PyContextVar *)ovar; - - if (!PyContextVar_CheckExact(var)) { - PyErr_SetString( - PyExc_TypeError, "an instance of ContextVar was expected"); - return NULL; - } - - PyContext *ctx = context_get(); - if (ctx == NULL) { - return NULL; - } - - PyObject *old_val = NULL; - int found = _PyHamt_Find(ctx->ctx_vars, (PyObject *)var, &old_val); - if (found < 0) { - return NULL; - } - - Py_XINCREF(old_val); - PyContextToken *tok = token_new(ctx, var, old_val); - Py_XDECREF(old_val); - - if (contextvar_set(var, val)) { - Py_DECREF(tok); - return NULL; - } - - return (PyObject *)tok; -} - - -int -PyContextVar_Reset(PyObject *ovar, PyObject *otok) -{ - ENSURE_ContextVar(ovar, -1) - ENSURE_ContextToken(otok, -1) - PyContextVar *var = (PyContextVar *)ovar; - PyContextToken *tok = (PyContextToken *)otok; - - if (tok->tok_used) { - PyErr_Format(PyExc_RuntimeError, - "%R has already been used once", tok); - return -1; - } - - if (var != tok->tok_var) { - PyErr_Format(PyExc_ValueError, - "%R was created by a different ContextVar", tok); - return -1; - } - - PyContext *ctx = context_get(); - if (ctx != tok->tok_ctx) { - PyErr_Format(PyExc_ValueError, - "%R was created in a different Context", tok); - return -1; - } - - tok->tok_used = 1; - - if (tok->tok_oldval == NULL) { - return contextvar_del(var); - } - else { - return contextvar_set(var, tok->tok_oldval); - } -} - - -/////////////////////////// PyContext - -/*[clinic input] -class _contextvars.Context "PyContext *" "&PyContext_Type" -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=bdf87f8e0cb580e8]*/ - - -static inline PyContext * -_context_alloc(void) -{ - struct _Py_context_state *state = get_context_state(); - PyContext *ctx; -#ifdef Py_DEBUG - // _context_alloc() must not be called after _PyContext_Fini() - assert(state->numfree != -1); -#endif - if (state->numfree) { - state->numfree--; - ctx = state->freelist; - state->freelist = (PyContext *)ctx->ctx_weakreflist; - ctx->ctx_weakreflist = NULL; - _Py_NewReference((PyObject *)ctx); - } - else { - ctx = PyObject_GC_New(PyContext, &PyContext_Type); - if (ctx == NULL) { - return NULL; - } - } - - ctx->ctx_vars = NULL; - ctx->ctx_prev = NULL; - ctx->ctx_entered = 0; - ctx->ctx_weakreflist = NULL; - - return ctx; -} - - -static PyContext * -context_new_empty(void) -{ - PyContext *ctx = _context_alloc(); - if (ctx == NULL) { - return NULL; - } - - ctx->ctx_vars = _PyHamt_New(); - if (ctx->ctx_vars == NULL) { - Py_DECREF(ctx); - return NULL; - } - - _PyObject_GC_TRACK(ctx); - return ctx; -} - - -static PyContext * -context_new_from_vars(PyHamtObject *vars) -{ - PyContext *ctx = _context_alloc(); - if (ctx == NULL) { - return NULL; - } - - Py_INCREF(vars); - ctx->ctx_vars = vars; - - _PyObject_GC_TRACK(ctx); - return ctx; -} - - -static inline PyContext * -context_get(void) -{ - PyThreadState *ts = _PyThreadState_GET(); - assert(ts != NULL); - PyContext *current_ctx = (PyContext *)ts->context; - if (current_ctx == NULL) { - current_ctx = context_new_empty(); - if (current_ctx == NULL) { - return NULL; - } - ts->context = (PyObject *)current_ctx; - } - return current_ctx; -} - -static int -context_check_key_type(PyObject *key) -{ - if (!PyContextVar_CheckExact(key)) { - // abort(); - PyErr_Format(PyExc_TypeError, - "a ContextVar key was expected, got %R", key); - return -1; - } - return 0; -} - -static PyObject * -context_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - if (PyTuple_Size(args) || (kwds != NULL && PyDict_Size(kwds))) { - PyErr_SetString( - PyExc_TypeError, "Context() does not accept any arguments"); - return NULL; - } - return PyContext_New(); -} - -static int -context_tp_clear(PyContext *self) -{ - Py_CLEAR(self->ctx_prev); - Py_CLEAR(self->ctx_vars); - return 0; -} - -static int -context_tp_traverse(PyContext *self, visitproc visit, void *arg) -{ - Py_VISIT(self->ctx_prev); - Py_VISIT(self->ctx_vars); - return 0; -} - -static void -context_tp_dealloc(PyContext *self) -{ - _PyObject_GC_UNTRACK(self); - - if (self->ctx_weakreflist != NULL) { - PyObject_ClearWeakRefs((PyObject*)self); - } - (void)context_tp_clear(self); - - struct _Py_context_state *state = get_context_state(); -#ifdef Py_DEBUG - // _context_alloc() must not be called after _PyContext_Fini() - assert(state->numfree != -1); -#endif - if (state->numfree < CONTEXT_FREELIST_MAXLEN) { - state->numfree++; - self->ctx_weakreflist = (PyObject *)state->freelist; - state->freelist = self; - } - else { - Py_TYPE(self)->tp_free(self); - } -} - -static PyObject * -context_tp_iter(PyContext *self) -{ - return _PyHamt_NewIterKeys(self->ctx_vars); -} - -static PyObject * -context_tp_richcompare(PyObject *v, PyObject *w, int op) -{ - if (!PyContext_CheckExact(v) || !PyContext_CheckExact(w) || - (op != Py_EQ && op != Py_NE)) - { - Py_RETURN_NOTIMPLEMENTED; - } - - int res = _PyHamt_Eq( - ((PyContext *)v)->ctx_vars, ((PyContext *)w)->ctx_vars); - if (res < 0) { - return NULL; - } - - if (op == Py_NE) { - res = !res; - } - - if (res) { - Py_RETURN_TRUE; - } - else { - Py_RETURN_FALSE; - } -} - -static Py_ssize_t -context_tp_len(PyContext *self) -{ - return _PyHamt_Len(self->ctx_vars); -} - -static PyObject * -context_tp_subscript(PyContext *self, PyObject *key) -{ - if (context_check_key_type(key)) { - return NULL; - } - PyObject *val = NULL; - int found = _PyHamt_Find(self->ctx_vars, key, &val); - if (found < 0) { - return NULL; - } - if (found == 0) { - PyErr_SetObject(PyExc_KeyError, key); - return NULL; - } - Py_INCREF(val); - return val; -} - -static int -context_tp_contains(PyContext *self, PyObject *key) -{ - if (context_check_key_type(key)) { - return -1; - } - PyObject *val = NULL; - return _PyHamt_Find(self->ctx_vars, key, &val); -} - - -/*[clinic input] -_contextvars.Context.get - key: object - default: object = None - / - -Return the value for `key` if `key` has the value in the context object. - -If `key` does not exist, return `default`. If `default` is not given, -return None. -[clinic start generated code]*/ - -static PyObject * -_contextvars_Context_get_impl(PyContext *self, PyObject *key, - PyObject *default_value) -/*[clinic end generated code: output=0c54aa7664268189 input=c8eeb81505023995]*/ -{ - if (context_check_key_type(key)) { - return NULL; - } - - PyObject *val = NULL; - int found = _PyHamt_Find(self->ctx_vars, key, &val); - if (found < 0) { - return NULL; - } - if (found == 0) { - Py_INCREF(default_value); - return default_value; - } - Py_INCREF(val); - return val; -} - - -/*[clinic input] -_contextvars.Context.items - -Return all variables and their values in the context object. - -The result is returned as a list of 2-tuples (variable, value). -[clinic start generated code]*/ - -static PyObject * -_contextvars_Context_items_impl(PyContext *self) -/*[clinic end generated code: output=fa1655c8a08502af input=00db64ae379f9f42]*/ -{ - return _PyHamt_NewIterItems(self->ctx_vars); -} - - -/*[clinic input] -_contextvars.Context.keys - -Return a list of all variables in the context object. -[clinic start generated code]*/ - -static PyObject * -_contextvars_Context_keys_impl(PyContext *self) -/*[clinic end generated code: output=177227c6b63ec0e2 input=114b53aebca3449c]*/ -{ - return _PyHamt_NewIterKeys(self->ctx_vars); -} - - -/*[clinic input] -_contextvars.Context.values - -Return a list of all variables' values in the context object. -[clinic start generated code]*/ - -static PyObject * -_contextvars_Context_values_impl(PyContext *self) -/*[clinic end generated code: output=d286dabfc8db6dde input=ce8075d04a6ea526]*/ -{ - return _PyHamt_NewIterValues(self->ctx_vars); -} - - -/*[clinic input] -_contextvars.Context.copy - -Return a shallow copy of the context object. -[clinic start generated code]*/ - -static PyObject * -_contextvars_Context_copy_impl(PyContext *self) -/*[clinic end generated code: output=30ba8896c4707a15 input=ebafdbdd9c72d592]*/ -{ - return (PyObject *)context_new_from_vars(self->ctx_vars); -} - - -static PyObject * -context_run(PyContext *self, PyObject *const *args, - Py_ssize_t nargs, PyObject *kwnames) -{ - PyThreadState *ts = _PyThreadState_GET(); - - if (nargs < 1) { - _PyErr_SetString(ts, PyExc_TypeError, - "run() missing 1 required positional argument"); - return NULL; - } - - if (_PyContext_Enter(ts, (PyObject *)self)) { - return NULL; - } - - PyObject *call_result = _PyObject_VectorcallTstate( - ts, args[0], args + 1, nargs - 1, kwnames); - - if (_PyContext_Exit(ts, (PyObject *)self)) { - return NULL; - } - - return call_result; -} - - -static PyMethodDef PyContext_methods[] = { - _CONTEXTVARS_CONTEXT_GET_METHODDEF - _CONTEXTVARS_CONTEXT_ITEMS_METHODDEF - _CONTEXTVARS_CONTEXT_KEYS_METHODDEF - _CONTEXTVARS_CONTEXT_VALUES_METHODDEF - _CONTEXTVARS_CONTEXT_COPY_METHODDEF - {"run", (PyCFunction)(void(*)(void))context_run, METH_FASTCALL | METH_KEYWORDS, NULL}, - {NULL, NULL} -}; - -static PySequenceMethods PyContext_as_sequence = { - 0, /* sq_length */ - 0, /* sq_concat */ - 0, /* sq_repeat */ - 0, /* sq_item */ - 0, /* sq_slice */ - 0, /* sq_ass_item */ - 0, /* sq_ass_slice */ - (objobjproc)context_tp_contains, /* sq_contains */ - 0, /* sq_inplace_concat */ - 0, /* sq_inplace_repeat */ -}; - -static PyMappingMethods PyContext_as_mapping = { - (lenfunc)context_tp_len, /* mp_length */ - (binaryfunc)context_tp_subscript, /* mp_subscript */ -}; - -PyTypeObject PyContext_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "_contextvars.Context", - sizeof(PyContext), - .tp_methods = PyContext_methods, - .tp_as_mapping = &PyContext_as_mapping, - .tp_as_sequence = &PyContext_as_sequence, - .tp_iter = (getiterfunc)context_tp_iter, - .tp_dealloc = (destructor)context_tp_dealloc, - .tp_getattro = PyObject_GenericGetAttr, - .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, - .tp_richcompare = context_tp_richcompare, - .tp_traverse = (traverseproc)context_tp_traverse, - .tp_clear = (inquiry)context_tp_clear, - .tp_new = context_tp_new, - .tp_weaklistoffset = offsetof(PyContext, ctx_weakreflist), - .tp_hash = PyObject_HashNotImplemented, -}; - - -/////////////////////////// ContextVar - - -static int -contextvar_set(PyContextVar *var, PyObject *val) -{ - var->var_cached = NULL; - PyThreadState *ts = PyThreadState_Get(); - - PyContext *ctx = context_get(); - if (ctx == NULL) { - return -1; - } - - PyHamtObject *new_vars = _PyHamt_Assoc( - ctx->ctx_vars, (PyObject *)var, val); - if (new_vars == NULL) { - return -1; - } - - Py_SETREF(ctx->ctx_vars, new_vars); - - var->var_cached = val; /* borrow */ - var->var_cached_tsid = ts->id; - var->var_cached_tsver = ts->context_ver; - return 0; -} - -static int -contextvar_del(PyContextVar *var) -{ - var->var_cached = NULL; - - PyContext *ctx = context_get(); - if (ctx == NULL) { - return -1; - } - - PyHamtObject *vars = ctx->ctx_vars; - PyHamtObject *new_vars = _PyHamt_Without(vars, (PyObject *)var); - if (new_vars == NULL) { - return -1; - } - - if (vars == new_vars) { - Py_DECREF(new_vars); - PyErr_SetObject(PyExc_LookupError, (PyObject *)var); - return -1; - } - - Py_SETREF(ctx->ctx_vars, new_vars); - return 0; -} - -static Py_hash_t -contextvar_generate_hash(void *addr, PyObject *name) -{ - /* Take hash of `name` and XOR it with the object's addr. - - The structure of the tree is encoded in objects' hashes, which - means that sufficiently similar hashes would result in tall trees - with many Collision nodes. Which would, in turn, result in slower - get and set operations. - - The XORing helps to ensure that: - - (1) sequentially allocated ContextVar objects have - different hashes; - - (2) context variables with equal names have - different hashes. - */ - - Py_hash_t name_hash = PyObject_Hash(name); - if (name_hash == -1) { - return -1; - } - - Py_hash_t res = _Py_HashPointer(addr) ^ name_hash; - return res == -1 ? -2 : res; -} - -static PyContextVar * -contextvar_new(PyObject *name, PyObject *def) -{ - if (!PyUnicode_Check(name)) { - PyErr_SetString(PyExc_TypeError, - "context variable name must be a str"); - return NULL; - } - - PyContextVar *var = PyObject_GC_New(PyContextVar, &PyContextVar_Type); - if (var == NULL) { - return NULL; - } - - var->var_hash = contextvar_generate_hash(var, name); - if (var->var_hash == -1) { - Py_DECREF(var); - return NULL; - } - - Py_INCREF(name); - var->var_name = name; - - Py_XINCREF(def); - var->var_default = def; - - var->var_cached = NULL; - var->var_cached_tsid = 0; - var->var_cached_tsver = 0; - - if (_PyObject_GC_MAY_BE_TRACKED(name) || - (def != NULL && _PyObject_GC_MAY_BE_TRACKED(def))) - { - PyObject_GC_Track(var); - } - return var; -} - - -/*[clinic input] -class _contextvars.ContextVar "PyContextVar *" "&PyContextVar_Type" -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=445da935fa8883c3]*/ - - -static PyObject * -contextvar_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - static char *kwlist[] = {"", "default", NULL}; - PyObject *name; - PyObject *def = NULL; - - if (!PyArg_ParseTupleAndKeywords( - args, kwds, "O|$O:ContextVar", kwlist, &name, &def)) - { - return NULL; - } - - return (PyObject *)contextvar_new(name, def); -} - -static int -contextvar_tp_clear(PyContextVar *self) -{ - Py_CLEAR(self->var_name); - Py_CLEAR(self->var_default); - self->var_cached = NULL; - self->var_cached_tsid = 0; - self->var_cached_tsver = 0; - return 0; -} - -static int -contextvar_tp_traverse(PyContextVar *self, visitproc visit, void *arg) -{ - Py_VISIT(self->var_name); - Py_VISIT(self->var_default); - return 0; -} - -static void -contextvar_tp_dealloc(PyContextVar *self) -{ - PyObject_GC_UnTrack(self); - (void)contextvar_tp_clear(self); - Py_TYPE(self)->tp_free(self); -} - -static Py_hash_t -contextvar_tp_hash(PyContextVar *self) -{ - return self->var_hash; -} - -static PyObject * -contextvar_tp_repr(PyContextVar *self) -{ - _PyUnicodeWriter writer; - - _PyUnicodeWriter_Init(&writer); - - if (_PyUnicodeWriter_WriteASCIIString( - &writer, "<ContextVar name=", 17) < 0) - { - goto error; - } - - PyObject *name = PyObject_Repr(self->var_name); - if (name == NULL) { - goto error; - } - if (_PyUnicodeWriter_WriteStr(&writer, name) < 0) { - Py_DECREF(name); - goto error; - } - Py_DECREF(name); - - if (self->var_default != NULL) { - if (_PyUnicodeWriter_WriteASCIIString(&writer, " default=", 9) < 0) { - goto error; - } - - PyObject *def = PyObject_Repr(self->var_default); - if (def == NULL) { - goto error; - } - if (_PyUnicodeWriter_WriteStr(&writer, def) < 0) { - Py_DECREF(def); - goto error; - } - Py_DECREF(def); - } - - PyObject *addr = PyUnicode_FromFormat(" at %p>", self); - if (addr == NULL) { - goto error; - } - if (_PyUnicodeWriter_WriteStr(&writer, addr) < 0) { - Py_DECREF(addr); - goto error; - } - Py_DECREF(addr); - - return _PyUnicodeWriter_Finish(&writer); - -error: - _PyUnicodeWriter_Dealloc(&writer); - return NULL; -} - - -/*[clinic input] -_contextvars.ContextVar.get - default: object = NULL - / - -Return a value for the context variable for the current context. - -If there is no value for the variable in the current context, the method will: - * return the value of the default argument of the method, if provided; or - * return the default value for the context variable, if it was created - with one; or - * raise a LookupError. -[clinic start generated code]*/ - -static PyObject * -_contextvars_ContextVar_get_impl(PyContextVar *self, PyObject *default_value) -/*[clinic end generated code: output=0746bd0aa2ced7bf input=30aa2ab9e433e401]*/ -{ - if (!PyContextVar_CheckExact(self)) { - PyErr_SetString( - PyExc_TypeError, "an instance of ContextVar was expected"); - return NULL; - } - - PyObject *val; - if (PyContextVar_Get((PyObject *)self, default_value, &val) < 0) { - return NULL; - } - - if (val == NULL) { - PyErr_SetObject(PyExc_LookupError, (PyObject *)self); - return NULL; - } - - return val; -} - -/*[clinic input] -_contextvars.ContextVar.set - value: object - / - -Call to set a new value for the context variable in the current context. - -The required value argument is the new value for the context variable. - -Returns a Token object that can be used to restore the variable to its previous -value via the `ContextVar.reset()` method. -[clinic start generated code]*/ - -static PyObject * -_contextvars_ContextVar_set(PyContextVar *self, PyObject *value) -/*[clinic end generated code: output=446ed5e820d6d60b input=c0a6887154227453]*/ -{ - return PyContextVar_Set((PyObject *)self, value); -} - -/*[clinic input] -_contextvars.ContextVar.reset - token: object - / - -Reset the context variable. - -The variable is reset to the value it had before the `ContextVar.set()` that -created the token was used. -[clinic start generated code]*/ - -static PyObject * -_contextvars_ContextVar_reset(PyContextVar *self, PyObject *token) -/*[clinic end generated code: output=d4ee34d0742d62ee input=ebe2881e5af4ffda]*/ -{ - if (!PyContextToken_CheckExact(token)) { - PyErr_Format(PyExc_TypeError, - "expected an instance of Token, got %R", token); - return NULL; - } - - if (PyContextVar_Reset((PyObject *)self, token)) { - return NULL; - } - - Py_RETURN_NONE; -} - - -static PyMemberDef PyContextVar_members[] = { - {"name", T_OBJECT, offsetof(PyContextVar, var_name), READONLY}, - {NULL} -}; - -static PyMethodDef PyContextVar_methods[] = { - _CONTEXTVARS_CONTEXTVAR_GET_METHODDEF - _CONTEXTVARS_CONTEXTVAR_SET_METHODDEF - _CONTEXTVARS_CONTEXTVAR_RESET_METHODDEF - {"__class_getitem__", (PyCFunction)Py_GenericAlias, - METH_O|METH_CLASS, PyDoc_STR("See PEP 585")}, - {NULL, NULL} -}; - -PyTypeObject PyContextVar_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "_contextvars.ContextVar", - sizeof(PyContextVar), - .tp_methods = PyContextVar_methods, - .tp_members = PyContextVar_members, - .tp_dealloc = (destructor)contextvar_tp_dealloc, - .tp_getattro = PyObject_GenericGetAttr, - .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, - .tp_traverse = (traverseproc)contextvar_tp_traverse, - .tp_clear = (inquiry)contextvar_tp_clear, - .tp_new = contextvar_tp_new, - .tp_free = PyObject_GC_Del, - .tp_hash = (hashfunc)contextvar_tp_hash, - .tp_repr = (reprfunc)contextvar_tp_repr, -}; - - -/////////////////////////// Token - -static PyObject * get_token_missing(void); - - -/*[clinic input] -class _contextvars.Token "PyContextToken *" "&PyContextToken_Type" -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=338a5e2db13d3f5b]*/ - - -static PyObject * -token_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - PyErr_SetString(PyExc_RuntimeError, - "Tokens can only be created by ContextVars"); - return NULL; -} - -static int -token_tp_clear(PyContextToken *self) -{ - Py_CLEAR(self->tok_ctx); - Py_CLEAR(self->tok_var); - Py_CLEAR(self->tok_oldval); - return 0; -} - -static int -token_tp_traverse(PyContextToken *self, visitproc visit, void *arg) -{ - Py_VISIT(self->tok_ctx); - Py_VISIT(self->tok_var); - Py_VISIT(self->tok_oldval); - return 0; -} - -static void -token_tp_dealloc(PyContextToken *self) -{ - PyObject_GC_UnTrack(self); - (void)token_tp_clear(self); - Py_TYPE(self)->tp_free(self); -} - -static PyObject * -token_tp_repr(PyContextToken *self) -{ - _PyUnicodeWriter writer; - - _PyUnicodeWriter_Init(&writer); - - if (_PyUnicodeWriter_WriteASCIIString(&writer, "<Token", 6) < 0) { - goto error; - } - - if (self->tok_used) { - if (_PyUnicodeWriter_WriteASCIIString(&writer, " used", 5) < 0) { - goto error; - } - } - - if (_PyUnicodeWriter_WriteASCIIString(&writer, " var=", 5) < 0) { - goto error; - } - - PyObject *var = PyObject_Repr((PyObject *)self->tok_var); - if (var == NULL) { - goto error; - } - if (_PyUnicodeWriter_WriteStr(&writer, var) < 0) { - Py_DECREF(var); - goto error; - } - Py_DECREF(var); - - PyObject *addr = PyUnicode_FromFormat(" at %p>", self); - if (addr == NULL) { - goto error; - } - if (_PyUnicodeWriter_WriteStr(&writer, addr) < 0) { - Py_DECREF(addr); - goto error; - } - Py_DECREF(addr); - - return _PyUnicodeWriter_Finish(&writer); - -error: - _PyUnicodeWriter_Dealloc(&writer); - return NULL; -} - -static PyObject * -token_get_var(PyContextToken *self, void *Py_UNUSED(ignored)) -{ - Py_INCREF(self->tok_var); - return (PyObject *)self->tok_var; -} - -static PyObject * -token_get_old_value(PyContextToken *self, void *Py_UNUSED(ignored)) -{ - if (self->tok_oldval == NULL) { - return get_token_missing(); - } - - Py_INCREF(self->tok_oldval); - return self->tok_oldval; -} - -static PyGetSetDef PyContextTokenType_getsetlist[] = { - {"var", (getter)token_get_var, NULL, NULL}, - {"old_value", (getter)token_get_old_value, NULL, NULL}, - {NULL} -}; - -static PyMethodDef PyContextTokenType_methods[] = { - {"__class_getitem__", (PyCFunction)Py_GenericAlias, - METH_O|METH_CLASS, PyDoc_STR("See PEP 585")}, - {NULL} -}; - -PyTypeObject PyContextToken_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "_contextvars.Token", - sizeof(PyContextToken), - .tp_methods = PyContextTokenType_methods, - .tp_getset = PyContextTokenType_getsetlist, - .tp_dealloc = (destructor)token_tp_dealloc, - .tp_getattro = PyObject_GenericGetAttr, - .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, - .tp_traverse = (traverseproc)token_tp_traverse, - .tp_clear = (inquiry)token_tp_clear, - .tp_new = token_tp_new, - .tp_free = PyObject_GC_Del, - .tp_hash = PyObject_HashNotImplemented, - .tp_repr = (reprfunc)token_tp_repr, -}; - -static PyContextToken * -token_new(PyContext *ctx, PyContextVar *var, PyObject *val) -{ - PyContextToken *tok = PyObject_GC_New(PyContextToken, &PyContextToken_Type); - if (tok == NULL) { - return NULL; - } - - Py_INCREF(ctx); - tok->tok_ctx = ctx; - - Py_INCREF(var); - tok->tok_var = var; - - Py_XINCREF(val); - tok->tok_oldval = val; - - tok->tok_used = 0; - - PyObject_GC_Track(tok); - return tok; -} - - -/////////////////////////// Token.MISSING - - -static PyObject *_token_missing; - - -typedef struct { - PyObject_HEAD -} PyContextTokenMissing; - - -static PyObject * -context_token_missing_tp_repr(PyObject *self) -{ - return PyUnicode_FromString("<Token.MISSING>"); -} - - -PyTypeObject PyContextTokenMissing_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "Token.MISSING", - sizeof(PyContextTokenMissing), - .tp_getattro = PyObject_GenericGetAttr, - .tp_flags = Py_TPFLAGS_DEFAULT, - .tp_repr = context_token_missing_tp_repr, -}; - - -static PyObject * -get_token_missing(void) -{ - if (_token_missing != NULL) { - Py_INCREF(_token_missing); - return _token_missing; - } - - _token_missing = (PyObject *)PyObject_New( - PyContextTokenMissing, &PyContextTokenMissing_Type); - if (_token_missing == NULL) { - return NULL; - } - - Py_INCREF(_token_missing); - return _token_missing; -} - - -/////////////////////////// - - -void -_PyContext_ClearFreeList(PyInterpreterState *interp) -{ - struct _Py_context_state *state = &interp->context; - for (; state->numfree; state->numfree--) { - PyContext *ctx = state->freelist; - state->freelist = (PyContext *)ctx->ctx_weakreflist; - ctx->ctx_weakreflist = NULL; - PyObject_GC_Del(ctx); - } -} - - -void -_PyContext_Fini(PyInterpreterState *interp) -{ - if (_Py_IsMainInterpreter(interp)) { - Py_CLEAR(_token_missing); - } - _PyContext_ClearFreeList(interp); -#ifdef Py_DEBUG - struct _Py_context_state *state = &interp->context; - state->numfree = -1; -#endif - _PyHamt_Fini(); -} - - -int -_PyContext_Init(void) -{ - if (!_PyHamt_Init()) { - return 0; - } - - if ((PyType_Ready(&PyContext_Type) < 0) || - (PyType_Ready(&PyContextVar_Type) < 0) || - (PyType_Ready(&PyContextToken_Type) < 0) || - (PyType_Ready(&PyContextTokenMissing_Type) < 0)) - { - return 0; - } - - PyObject *missing = get_token_missing(); - if (PyDict_SetItemString( - PyContextToken_Type.tp_dict, "MISSING", missing)) - { - Py_DECREF(missing); - return 0; - } - Py_DECREF(missing); - - return 1; -} diff --git a/contrib/tools/python3/src/Python/dtoa.c b/contrib/tools/python3/src/Python/dtoa.c deleted file mode 100644 index e629b296426..00000000000 --- a/contrib/tools/python3/src/Python/dtoa.c +++ /dev/null @@ -1,2859 +0,0 @@ -/**************************************************************** - * - * The author of this software is David M. Gay. - * - * Copyright (c) 1991, 2000, 2001 by Lucent Technologies. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose without fee is hereby granted, provided that this entire notice - * is included in all copies of any software which is or includes a copy - * or modification of this software and in all copies of the supporting - * documentation for such software. - * - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR LUCENT MAKES ANY - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. - * - ***************************************************************/ - -/**************************************************************** - * This is dtoa.c by David M. Gay, downloaded from - * http://www.netlib.org/fp/dtoa.c on April 15, 2009 and modified for - * inclusion into the Python core by Mark E. T. Dickinson and Eric V. Smith. - * - * Please remember to check http://www.netlib.org/fp regularly (and especially - * before any Python release) for bugfixes and updates. - * - * The major modifications from Gay's original code are as follows: - * - * 0. The original code has been specialized to Python's needs by removing - * many of the #ifdef'd sections. In particular, code to support VAX and - * IBM floating-point formats, hex NaNs, hex floats, locale-aware - * treatment of the decimal point, and setting of the inexact flag have - * been removed. - * - * 1. We use PyMem_Malloc and PyMem_Free in place of malloc and free. - * - * 2. The public functions strtod, dtoa and freedtoa all now have - * a _Py_dg_ prefix. - * - * 3. Instead of assuming that PyMem_Malloc always succeeds, we thread - * PyMem_Malloc failures through the code. The functions - * - * Balloc, multadd, s2b, i2b, mult, pow5mult, lshift, diff, d2b - * - * of return type *Bigint all return NULL to indicate a malloc failure. - * Similarly, rv_alloc and nrv_alloc (return type char *) return NULL on - * failure. bigcomp now has return type int (it used to be void) and - * returns -1 on failure and 0 otherwise. _Py_dg_dtoa returns NULL - * on failure. _Py_dg_strtod indicates failure due to malloc failure - * by returning -1.0, setting errno=ENOMEM and *se to s00. - * - * 4. The static variable dtoa_result has been removed. Callers of - * _Py_dg_dtoa are expected to call _Py_dg_freedtoa to free - * the memory allocated by _Py_dg_dtoa. - * - * 5. The code has been reformatted to better fit with Python's - * C style guide (PEP 7). - * - * 6. A bug in the memory allocation has been fixed: to avoid FREEing memory - * that hasn't been MALLOC'ed, private_mem should only be used when k <= - * Kmax. - * - * 7. _Py_dg_strtod has been modified so that it doesn't accept strings with - * leading whitespace. - * - * 8. A corner case where _Py_dg_dtoa didn't strip trailing zeros has been - * fixed. (bugs.python.org/issue40780) - * - ***************************************************************/ - -/* Please send bug reports for the original dtoa.c code to David M. Gay (dmg - * at acm dot org, with " at " changed at "@" and " dot " changed to "."). - * Please report bugs for this modified version using the Python issue tracker - * (http://bugs.python.org). */ - -/* On a machine with IEEE extended-precision registers, it is - * necessary to specify double-precision (53-bit) rounding precision - * before invoking strtod or dtoa. If the machine uses (the equivalent - * of) Intel 80x87 arithmetic, the call - * _control87(PC_53, MCW_PC); - * does this with many compilers. Whether this or another call is - * appropriate depends on the compiler; for this to work, it may be - * necessary to #include "float.h" or another system-dependent header - * file. - */ - -/* strtod for IEEE-, VAX-, and IBM-arithmetic machines. - * - * This strtod returns a nearest machine number to the input decimal - * string (or sets errno to ERANGE). With IEEE arithmetic, ties are - * broken by the IEEE round-even rule. Otherwise ties are broken by - * biased rounding (add half and chop). - * - * Inspired loosely by William D. Clinger's paper "How to Read Floating - * Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 92-101]. - * - * Modifications: - * - * 1. We only require IEEE, IBM, or VAX double-precision - * arithmetic (not IEEE double-extended). - * 2. We get by with floating-point arithmetic in a case that - * Clinger missed -- when we're computing d * 10^n - * for a small integer d and the integer n is not too - * much larger than 22 (the maximum integer k for which - * we can represent 10^k exactly), we may be able to - * compute (d*10^k) * 10^(e-k) with just one roundoff. - * 3. Rather than a bit-at-a-time adjustment of the binary - * result in the hard case, we use floating-point - * arithmetic to determine the adjustment to within - * one bit; only in really hard cases do we need to - * compute a second residual. - * 4. Because of 3., we don't need a large table of powers of 10 - * for ten-to-e (just some small tables, e.g. of 10^k - * for 0 <= k <= 22). - */ - -/* Linking of Python's #defines to Gay's #defines starts here. */ - -#include "Python.h" -#include "pycore_dtoa.h" - -/* if PY_NO_SHORT_FLOAT_REPR is defined, then don't even try to compile - the following code */ -#ifndef PY_NO_SHORT_FLOAT_REPR - -#include "float.h" - -#define MALLOC PyMem_Malloc -#define FREE PyMem_Free - -/* This code should also work for ARM mixed-endian format on little-endian - machines, where doubles have byte order 45670123 (in increasing address - order, 0 being the least significant byte). */ -#ifdef DOUBLE_IS_LITTLE_ENDIAN_IEEE754 -# define IEEE_8087 -#endif -#if defined(DOUBLE_IS_BIG_ENDIAN_IEEE754) || \ - defined(DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754) -# define IEEE_MC68k -#endif -#if defined(IEEE_8087) + defined(IEEE_MC68k) != 1 -#error "Exactly one of IEEE_8087 or IEEE_MC68k should be defined." -#endif - -/* The code below assumes that the endianness of integers matches the - endianness of the two 32-bit words of a double. Check this. */ -#if defined(WORDS_BIGENDIAN) && (defined(DOUBLE_IS_LITTLE_ENDIAN_IEEE754) || \ - defined(DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754)) -#error "doubles and ints have incompatible endianness" -#endif - -#if !defined(WORDS_BIGENDIAN) && defined(DOUBLE_IS_BIG_ENDIAN_IEEE754) -#error "doubles and ints have incompatible endianness" -#endif - - -typedef uint32_t ULong; -typedef int32_t Long; -typedef uint64_t ULLong; - -#undef DEBUG -#ifdef Py_DEBUG -#define DEBUG -#endif - -/* End Python #define linking */ - -#ifdef DEBUG -#define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);} -#endif - -#ifndef PRIVATE_MEM -#define PRIVATE_MEM 2304 -#endif -#define PRIVATE_mem ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double)) -static double private_mem[PRIVATE_mem], *pmem_next = private_mem; - -#ifdef __cplusplus -extern "C" { -#endif - -typedef union { double d; ULong L[2]; } U; - -#ifdef IEEE_8087 -#define word0(x) (x)->L[1] -#define word1(x) (x)->L[0] -#else -#define word0(x) (x)->L[0] -#define word1(x) (x)->L[1] -#endif -#define dval(x) (x)->d - -#ifndef STRTOD_DIGLIM -#define STRTOD_DIGLIM 40 -#endif - -/* maximum permitted exponent value for strtod; exponents larger than - MAX_ABS_EXP in absolute value get truncated to +-MAX_ABS_EXP. MAX_ABS_EXP - should fit into an int. */ -#ifndef MAX_ABS_EXP -#define MAX_ABS_EXP 1100000000U -#endif -/* Bound on length of pieces of input strings in _Py_dg_strtod; specifically, - this is used to bound the total number of digits ignoring leading zeros and - the number of digits that follow the decimal point. Ideally, MAX_DIGITS - should satisfy MAX_DIGITS + 400 < MAX_ABS_EXP; that ensures that the - exponent clipping in _Py_dg_strtod can't affect the value of the output. */ -#ifndef MAX_DIGITS -#define MAX_DIGITS 1000000000U -#endif - -/* Guard against trying to use the above values on unusual platforms with ints - * of width less than 32 bits. */ -#if MAX_ABS_EXP > INT_MAX -#error "MAX_ABS_EXP should fit in an int" -#endif -#if MAX_DIGITS > INT_MAX -#error "MAX_DIGITS should fit in an int" -#endif - -/* The following definition of Storeinc is appropriate for MIPS processors. - * An alternative that might be better on some machines is - * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff) - */ -#if defined(IEEE_8087) -#define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \ - ((unsigned short *)a)[0] = (unsigned short)c, a++) -#else -#define Storeinc(a,b,c) (((unsigned short *)a)[0] = (unsigned short)b, \ - ((unsigned short *)a)[1] = (unsigned short)c, a++) -#endif - -/* #define P DBL_MANT_DIG */ -/* Ten_pmax = floor(P*log(2)/log(5)) */ -/* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */ -/* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */ -/* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */ - -#define Exp_shift 20 -#define Exp_shift1 20 -#define Exp_msk1 0x100000 -#define Exp_msk11 0x100000 -#define Exp_mask 0x7ff00000 -#define P 53 -#define Nbits 53 -#define Bias 1023 -#define Emax 1023 -#define Emin (-1022) -#define Etiny (-1074) /* smallest denormal is 2**Etiny */ -#define Exp_1 0x3ff00000 -#define Exp_11 0x3ff00000 -#define Ebits 11 -#define Frac_mask 0xfffff -#define Frac_mask1 0xfffff -#define Ten_pmax 22 -#define Bletch 0x10 -#define Bndry_mask 0xfffff -#define Bndry_mask1 0xfffff -#define Sign_bit 0x80000000 -#define Log2P 1 -#define Tiny0 0 -#define Tiny1 1 -#define Quick_max 14 -#define Int_max 14 - -#ifndef Flt_Rounds -#ifdef FLT_ROUNDS -#define Flt_Rounds FLT_ROUNDS -#else -#define Flt_Rounds 1 -#endif -#endif /*Flt_Rounds*/ - -#define Rounding Flt_Rounds - -#define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1)) -#define Big1 0xffffffff - -/* Standard NaN used by _Py_dg_stdnan. */ - -#define NAN_WORD0 0x7ff80000 -#define NAN_WORD1 0 - -/* Bits of the representation of positive infinity. */ - -#define POSINF_WORD0 0x7ff00000 -#define POSINF_WORD1 0 - -/* struct BCinfo is used to pass information from _Py_dg_strtod to bigcomp */ - -typedef struct BCinfo BCinfo; -struct -BCinfo { - int e0, nd, nd0, scale; -}; - -#define FFFFFFFF 0xffffffffUL - -#define Kmax 7 - -/* struct Bigint is used to represent arbitrary-precision integers. These - integers are stored in sign-magnitude format, with the magnitude stored as - an array of base 2**32 digits. Bigints are always normalized: if x is a - Bigint then x->wds >= 1, and either x->wds == 1 or x[wds-1] is nonzero. - - The Bigint fields are as follows: - - - next is a header used by Balloc and Bfree to keep track of lists - of freed Bigints; it's also used for the linked list of - powers of 5 of the form 5**2**i used by pow5mult. - - k indicates which pool this Bigint was allocated from - - maxwds is the maximum number of words space was allocated for - (usually maxwds == 2**k) - - sign is 1 for negative Bigints, 0 for positive. The sign is unused - (ignored on inputs, set to 0 on outputs) in almost all operations - involving Bigints: a notable exception is the diff function, which - ignores signs on inputs but sets the sign of the output correctly. - - wds is the actual number of significant words - - x contains the vector of words (digits) for this Bigint, from least - significant (x[0]) to most significant (x[wds-1]). -*/ - -struct -Bigint { - struct Bigint *next; - int k, maxwds, sign, wds; - ULong x[1]; -}; - -typedef struct Bigint Bigint; - -#ifndef Py_USING_MEMORY_DEBUGGER - -/* Memory management: memory is allocated from, and returned to, Kmax+1 pools - of memory, where pool k (0 <= k <= Kmax) is for Bigints b with b->maxwds == - 1 << k. These pools are maintained as linked lists, with freelist[k] - pointing to the head of the list for pool k. - - On allocation, if there's no free slot in the appropriate pool, MALLOC is - called to get more memory. This memory is not returned to the system until - Python quits. There's also a private memory pool that's allocated from - in preference to using MALLOC. - - For Bigints with more than (1 << Kmax) digits (which implies at least 1233 - decimal digits), memory is directly allocated using MALLOC, and freed using - FREE. - - XXX: it would be easy to bypass this memory-management system and - translate each call to Balloc into a call to PyMem_Malloc, and each - Bfree to PyMem_Free. Investigate whether this has any significant - performance on impact. */ - -static Bigint *freelist[Kmax+1]; - -/* Allocate space for a Bigint with up to 1<<k digits */ - -static Bigint * -Balloc(int k) -{ - int x; - Bigint *rv; - unsigned int len; - - if (k <= Kmax && (rv = freelist[k])) - freelist[k] = rv->next; - else { - x = 1 << k; - len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1) - /sizeof(double); - if (k <= Kmax && pmem_next - private_mem + len <= (Py_ssize_t)PRIVATE_mem) { - rv = (Bigint*)pmem_next; - pmem_next += len; - } - else { - rv = (Bigint*)MALLOC(len*sizeof(double)); - if (rv == NULL) - return NULL; - } - rv->k = k; - rv->maxwds = x; - } - rv->sign = rv->wds = 0; - return rv; -} - -/* Free a Bigint allocated with Balloc */ - -static void -Bfree(Bigint *v) -{ - if (v) { - if (v->k > Kmax) - FREE((void*)v); - else { - v->next = freelist[v->k]; - freelist[v->k] = v; - } - } -} - -#else - -/* Alternative versions of Balloc and Bfree that use PyMem_Malloc and - PyMem_Free directly in place of the custom memory allocation scheme above. - These are provided for the benefit of memory debugging tools like - Valgrind. */ - -/* Allocate space for a Bigint with up to 1<<k digits */ - -static Bigint * -Balloc(int k) -{ - int x; - Bigint *rv; - unsigned int len; - - x = 1 << k; - len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1) - /sizeof(double); - - rv = (Bigint*)MALLOC(len*sizeof(double)); - if (rv == NULL) - return NULL; - - rv->k = k; - rv->maxwds = x; - rv->sign = rv->wds = 0; - return rv; -} - -/* Free a Bigint allocated with Balloc */ - -static void -Bfree(Bigint *v) -{ - if (v) { - FREE((void*)v); - } -} - -#endif /* Py_USING_MEMORY_DEBUGGER */ - -#define Bcopy(x,y) memcpy((char *)&x->sign, (char *)&y->sign, \ - y->wds*sizeof(Long) + 2*sizeof(int)) - -/* Multiply a Bigint b by m and add a. Either modifies b in place and returns - a pointer to the modified b, or Bfrees b and returns a pointer to a copy. - On failure, return NULL. In this case, b will have been already freed. */ - -static Bigint * -multadd(Bigint *b, int m, int a) /* multiply by m and add a */ -{ - int i, wds; - ULong *x; - ULLong carry, y; - Bigint *b1; - - wds = b->wds; - x = b->x; - i = 0; - carry = a; - do { - y = *x * (ULLong)m + carry; - carry = y >> 32; - *x++ = (ULong)(y & FFFFFFFF); - } - while(++i < wds); - if (carry) { - if (wds >= b->maxwds) { - b1 = Balloc(b->k+1); - if (b1 == NULL){ - Bfree(b); - return NULL; - } - Bcopy(b1, b); - Bfree(b); - b = b1; - } - b->x[wds++] = (ULong)carry; - b->wds = wds; - } - return b; -} - -/* convert a string s containing nd decimal digits (possibly containing a - decimal separator at position nd0, which is ignored) to a Bigint. This - function carries on where the parsing code in _Py_dg_strtod leaves off: on - entry, y9 contains the result of converting the first 9 digits. Returns - NULL on failure. */ - -static Bigint * -s2b(const char *s, int nd0, int nd, ULong y9) -{ - Bigint *b; - int i, k; - Long x, y; - - x = (nd + 8) / 9; - for(k = 0, y = 1; x > y; y <<= 1, k++) ; - b = Balloc(k); - if (b == NULL) - return NULL; - b->x[0] = y9; - b->wds = 1; - - if (nd <= 9) - return b; - - s += 9; - for (i = 9; i < nd0; i++) { - b = multadd(b, 10, *s++ - '0'); - if (b == NULL) - return NULL; - } - s++; - for(; i < nd; i++) { - b = multadd(b, 10, *s++ - '0'); - if (b == NULL) - return NULL; - } - return b; -} - -/* count leading 0 bits in the 32-bit integer x. */ - -static int -hi0bits(ULong x) -{ - int k = 0; - - if (!(x & 0xffff0000)) { - k = 16; - x <<= 16; - } - if (!(x & 0xff000000)) { - k += 8; - x <<= 8; - } - if (!(x & 0xf0000000)) { - k += 4; - x <<= 4; - } - if (!(x & 0xc0000000)) { - k += 2; - x <<= 2; - } - if (!(x & 0x80000000)) { - k++; - if (!(x & 0x40000000)) - return 32; - } - return k; -} - -/* count trailing 0 bits in the 32-bit integer y, and shift y right by that - number of bits. */ - -static int -lo0bits(ULong *y) -{ - int k; - ULong x = *y; - - if (x & 7) { - if (x & 1) - return 0; - if (x & 2) { - *y = x >> 1; - return 1; - } - *y = x >> 2; - return 2; - } - k = 0; - if (!(x & 0xffff)) { - k = 16; - x >>= 16; - } - if (!(x & 0xff)) { - k += 8; - x >>= 8; - } - if (!(x & 0xf)) { - k += 4; - x >>= 4; - } - if (!(x & 0x3)) { - k += 2; - x >>= 2; - } - if (!(x & 1)) { - k++; - x >>= 1; - if (!x) - return 32; - } - *y = x; - return k; -} - -/* convert a small nonnegative integer to a Bigint */ - -static Bigint * -i2b(int i) -{ - Bigint *b; - - b = Balloc(1); - if (b == NULL) - return NULL; - b->x[0] = i; - b->wds = 1; - return b; -} - -/* multiply two Bigints. Returns a new Bigint, or NULL on failure. Ignores - the signs of a and b. */ - -static Bigint * -mult(Bigint *a, Bigint *b) -{ - Bigint *c; - int k, wa, wb, wc; - ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0; - ULong y; - ULLong carry, z; - - if ((!a->x[0] && a->wds == 1) || (!b->x[0] && b->wds == 1)) { - c = Balloc(0); - if (c == NULL) - return NULL; - c->wds = 1; - c->x[0] = 0; - return c; - } - - if (a->wds < b->wds) { - c = a; - a = b; - b = c; - } - k = a->k; - wa = a->wds; - wb = b->wds; - wc = wa + wb; - if (wc > a->maxwds) - k++; - c = Balloc(k); - if (c == NULL) - return NULL; - for(x = c->x, xa = x + wc; x < xa; x++) - *x = 0; - xa = a->x; - xae = xa + wa; - xb = b->x; - xbe = xb + wb; - xc0 = c->x; - for(; xb < xbe; xc0++) { - if ((y = *xb++)) { - x = xa; - xc = xc0; - carry = 0; - do { - z = *x++ * (ULLong)y + *xc + carry; - carry = z >> 32; - *xc++ = (ULong)(z & FFFFFFFF); - } - while(x < xae); - *xc = (ULong)carry; - } - } - for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ; - c->wds = wc; - return c; -} - -#ifndef Py_USING_MEMORY_DEBUGGER - -/* p5s is a linked list of powers of 5 of the form 5**(2**i), i >= 2 */ - -static Bigint *p5s; - -/* multiply the Bigint b by 5**k. Returns a pointer to the result, or NULL on - failure; if the returned pointer is distinct from b then the original - Bigint b will have been Bfree'd. Ignores the sign of b. */ - -static Bigint * -pow5mult(Bigint *b, int k) -{ - Bigint *b1, *p5, *p51; - int i; - static const int p05[3] = { 5, 25, 125 }; - - if ((i = k & 3)) { - b = multadd(b, p05[i-1], 0); - if (b == NULL) - return NULL; - } - - if (!(k >>= 2)) - return b; - p5 = p5s; - if (!p5) { - /* first time */ - p5 = i2b(625); - if (p5 == NULL) { - Bfree(b); - return NULL; - } - p5s = p5; - p5->next = 0; - } - for(;;) { - if (k & 1) { - b1 = mult(b, p5); - Bfree(b); - b = b1; - if (b == NULL) - return NULL; - } - if (!(k >>= 1)) - break; - p51 = p5->next; - if (!p51) { - p51 = mult(p5,p5); - if (p51 == NULL) { - Bfree(b); - return NULL; - } - p51->next = 0; - p5->next = p51; - } - p5 = p51; - } - return b; -} - -#else - -/* Version of pow5mult that doesn't cache powers of 5. Provided for - the benefit of memory debugging tools like Valgrind. */ - -static Bigint * -pow5mult(Bigint *b, int k) -{ - Bigint *b1, *p5, *p51; - int i; - static const int p05[3] = { 5, 25, 125 }; - - if ((i = k & 3)) { - b = multadd(b, p05[i-1], 0); - if (b == NULL) - return NULL; - } - - if (!(k >>= 2)) - return b; - p5 = i2b(625); - if (p5 == NULL) { - Bfree(b); - return NULL; - } - - for(;;) { - if (k & 1) { - b1 = mult(b, p5); - Bfree(b); - b = b1; - if (b == NULL) { - Bfree(p5); - return NULL; - } - } - if (!(k >>= 1)) - break; - p51 = mult(p5, p5); - Bfree(p5); - p5 = p51; - if (p5 == NULL) { - Bfree(b); - return NULL; - } - } - Bfree(p5); - return b; -} - -#endif /* Py_USING_MEMORY_DEBUGGER */ - -/* shift a Bigint b left by k bits. Return a pointer to the shifted result, - or NULL on failure. If the returned pointer is distinct from b then the - original b will have been Bfree'd. Ignores the sign of b. */ - -static Bigint * -lshift(Bigint *b, int k) -{ - int i, k1, n, n1; - Bigint *b1; - ULong *x, *x1, *xe, z; - - if (!k || (!b->x[0] && b->wds == 1)) - return b; - - n = k >> 5; - k1 = b->k; - n1 = n + b->wds + 1; - for(i = b->maxwds; n1 > i; i <<= 1) - k1++; - b1 = Balloc(k1); - if (b1 == NULL) { - Bfree(b); - return NULL; - } - x1 = b1->x; - for(i = 0; i < n; i++) - *x1++ = 0; - x = b->x; - xe = x + b->wds; - if (k &= 0x1f) { - k1 = 32 - k; - z = 0; - do { - *x1++ = *x << k | z; - z = *x++ >> k1; - } - while(x < xe); - if ((*x1 = z)) - ++n1; - } - else do - *x1++ = *x++; - while(x < xe); - b1->wds = n1 - 1; - Bfree(b); - return b1; -} - -/* Do a three-way compare of a and b, returning -1 if a < b, 0 if a == b and - 1 if a > b. Ignores signs of a and b. */ - -static int -cmp(Bigint *a, Bigint *b) -{ - ULong *xa, *xa0, *xb, *xb0; - int i, j; - - i = a->wds; - j = b->wds; -#ifdef DEBUG - if (i > 1 && !a->x[i-1]) - Bug("cmp called with a->x[a->wds-1] == 0"); - if (j > 1 && !b->x[j-1]) - Bug("cmp called with b->x[b->wds-1] == 0"); -#endif - if (i -= j) - return i; - xa0 = a->x; - xa = xa0 + j; - xb0 = b->x; - xb = xb0 + j; - for(;;) { - if (*--xa != *--xb) - return *xa < *xb ? -1 : 1; - if (xa <= xa0) - break; - } - return 0; -} - -/* Take the difference of Bigints a and b, returning a new Bigint. Returns - NULL on failure. The signs of a and b are ignored, but the sign of the - result is set appropriately. */ - -static Bigint * -diff(Bigint *a, Bigint *b) -{ - Bigint *c; - int i, wa, wb; - ULong *xa, *xae, *xb, *xbe, *xc; - ULLong borrow, y; - - i = cmp(a,b); - if (!i) { - c = Balloc(0); - if (c == NULL) - return NULL; - c->wds = 1; - c->x[0] = 0; - return c; - } - if (i < 0) { - c = a; - a = b; - b = c; - i = 1; - } - else - i = 0; - c = Balloc(a->k); - if (c == NULL) - return NULL; - c->sign = i; - wa = a->wds; - xa = a->x; - xae = xa + wa; - wb = b->wds; - xb = b->x; - xbe = xb + wb; - xc = c->x; - borrow = 0; - do { - y = (ULLong)*xa++ - *xb++ - borrow; - borrow = y >> 32 & (ULong)1; - *xc++ = (ULong)(y & FFFFFFFF); - } - while(xb < xbe); - while(xa < xae) { - y = *xa++ - borrow; - borrow = y >> 32 & (ULong)1; - *xc++ = (ULong)(y & FFFFFFFF); - } - while(!*--xc) - wa--; - c->wds = wa; - return c; -} - -/* Given a positive normal double x, return the difference between x and the - next double up. Doesn't give correct results for subnormals. */ - -static double -ulp(U *x) -{ - Long L; - U u; - - L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1; - word0(&u) = L; - word1(&u) = 0; - return dval(&u); -} - -/* Convert a Bigint to a double plus an exponent */ - -static double -b2d(Bigint *a, int *e) -{ - ULong *xa, *xa0, w, y, z; - int k; - U d; - - xa0 = a->x; - xa = xa0 + a->wds; - y = *--xa; -#ifdef DEBUG - if (!y) Bug("zero y in b2d"); -#endif - k = hi0bits(y); - *e = 32 - k; - if (k < Ebits) { - word0(&d) = Exp_1 | y >> (Ebits - k); - w = xa > xa0 ? *--xa : 0; - word1(&d) = y << ((32-Ebits) + k) | w >> (Ebits - k); - goto ret_d; - } - z = xa > xa0 ? *--xa : 0; - if (k -= Ebits) { - word0(&d) = Exp_1 | y << k | z >> (32 - k); - y = xa > xa0 ? *--xa : 0; - word1(&d) = z << k | y >> (32 - k); - } - else { - word0(&d) = Exp_1 | y; - word1(&d) = z; - } - ret_d: - return dval(&d); -} - -/* Convert a scaled double to a Bigint plus an exponent. Similar to d2b, - except that it accepts the scale parameter used in _Py_dg_strtod (which - should be either 0 or 2*P), and the normalization for the return value is - different (see below). On input, d should be finite and nonnegative, and d - / 2**scale should be exactly representable as an IEEE 754 double. - - Returns a Bigint b and an integer e such that - - dval(d) / 2**scale = b * 2**e. - - Unlike d2b, b is not necessarily odd: b and e are normalized so - that either 2**(P-1) <= b < 2**P and e >= Etiny, or b < 2**P - and e == Etiny. This applies equally to an input of 0.0: in that - case the return values are b = 0 and e = Etiny. - - The above normalization ensures that for all possible inputs d, - 2**e gives ulp(d/2**scale). - - Returns NULL on failure. -*/ - -static Bigint * -sd2b(U *d, int scale, int *e) -{ - Bigint *b; - - b = Balloc(1); - if (b == NULL) - return NULL; - - /* First construct b and e assuming that scale == 0. */ - b->wds = 2; - b->x[0] = word1(d); - b->x[1] = word0(d) & Frac_mask; - *e = Etiny - 1 + (int)((word0(d) & Exp_mask) >> Exp_shift); - if (*e < Etiny) - *e = Etiny; - else - b->x[1] |= Exp_msk1; - - /* Now adjust for scale, provided that b != 0. */ - if (scale && (b->x[0] || b->x[1])) { - *e -= scale; - if (*e < Etiny) { - scale = Etiny - *e; - *e = Etiny; - /* We can't shift more than P-1 bits without shifting out a 1. */ - assert(0 < scale && scale <= P - 1); - if (scale >= 32) { - /* The bits shifted out should all be zero. */ - assert(b->x[0] == 0); - b->x[0] = b->x[1]; - b->x[1] = 0; - scale -= 32; - } - if (scale) { - /* The bits shifted out should all be zero. */ - assert(b->x[0] << (32 - scale) == 0); - b->x[0] = (b->x[0] >> scale) | (b->x[1] << (32 - scale)); - b->x[1] >>= scale; - } - } - } - /* Ensure b is normalized. */ - if (!b->x[1]) - b->wds = 1; - - return b; -} - -/* Convert a double to a Bigint plus an exponent. Return NULL on failure. - - Given a finite nonzero double d, return an odd Bigint b and exponent *e - such that fabs(d) = b * 2**e. On return, *bbits gives the number of - significant bits of b; that is, 2**(*bbits-1) <= b < 2**(*bbits). - - If d is zero, then b == 0, *e == -1010, *bbits = 0. - */ - -static Bigint * -d2b(U *d, int *e, int *bits) -{ - Bigint *b; - int de, k; - ULong *x, y, z; - int i; - - b = Balloc(1); - if (b == NULL) - return NULL; - x = b->x; - - z = word0(d) & Frac_mask; - word0(d) &= 0x7fffffff; /* clear sign bit, which we ignore */ - if ((de = (int)(word0(d) >> Exp_shift))) - z |= Exp_msk1; - if ((y = word1(d))) { - if ((k = lo0bits(&y))) { - x[0] = y | z << (32 - k); - z >>= k; - } - else - x[0] = y; - i = - b->wds = (x[1] = z) ? 2 : 1; - } - else { - k = lo0bits(&z); - x[0] = z; - i = - b->wds = 1; - k += 32; - } - if (de) { - *e = de - Bias - (P-1) + k; - *bits = P - k; - } - else { - *e = de - Bias - (P-1) + 1 + k; - *bits = 32*i - hi0bits(x[i-1]); - } - return b; -} - -/* Compute the ratio of two Bigints, as a double. The result may have an - error of up to 2.5 ulps. */ - -static double -ratio(Bigint *a, Bigint *b) -{ - U da, db; - int k, ka, kb; - - dval(&da) = b2d(a, &ka); - dval(&db) = b2d(b, &kb); - k = ka - kb + 32*(a->wds - b->wds); - if (k > 0) - word0(&da) += k*Exp_msk1; - else { - k = -k; - word0(&db) += k*Exp_msk1; - } - return dval(&da) / dval(&db); -} - -static const double -tens[] = { - 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, - 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, - 1e20, 1e21, 1e22 -}; - -static const double -bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 }; -static const double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, - 9007199254740992.*9007199254740992.e-256 - /* = 2^106 * 1e-256 */ -}; -/* The factor of 2^53 in tinytens[4] helps us avoid setting the underflow */ -/* flag unnecessarily. It leads to a song and dance at the end of strtod. */ -#define Scale_Bit 0x10 -#define n_bigtens 5 - -#define ULbits 32 -#define kshift 5 -#define kmask 31 - - -static int -dshift(Bigint *b, int p2) -{ - int rv = hi0bits(b->x[b->wds-1]) - 4; - if (p2 > 0) - rv -= p2; - return rv & kmask; -} - -/* special case of Bigint division. The quotient is always in the range 0 <= - quotient < 10, and on entry the divisor S is normalized so that its top 4 - bits (28--31) are zero and bit 27 is set. */ - -static int -quorem(Bigint *b, Bigint *S) -{ - int n; - ULong *bx, *bxe, q, *sx, *sxe; - ULLong borrow, carry, y, ys; - - n = S->wds; -#ifdef DEBUG - /*debug*/ if (b->wds > n) - /*debug*/ Bug("oversize b in quorem"); -#endif - if (b->wds < n) - return 0; - sx = S->x; - sxe = sx + --n; - bx = b->x; - bxe = bx + n; - q = *bxe / (*sxe + 1); /* ensure q <= true quotient */ -#ifdef DEBUG - /*debug*/ if (q > 9) - /*debug*/ Bug("oversized quotient in quorem"); -#endif - if (q) { - borrow = 0; - carry = 0; - do { - ys = *sx++ * (ULLong)q + carry; - carry = ys >> 32; - y = *bx - (ys & FFFFFFFF) - borrow; - borrow = y >> 32 & (ULong)1; - *bx++ = (ULong)(y & FFFFFFFF); - } - while(sx <= sxe); - if (!*bxe) { - bx = b->x; - while(--bxe > bx && !*bxe) - --n; - b->wds = n; - } - } - if (cmp(b, S) >= 0) { - q++; - borrow = 0; - carry = 0; - bx = b->x; - sx = S->x; - do { - ys = *sx++ + carry; - carry = ys >> 32; - y = *bx - (ys & FFFFFFFF) - borrow; - borrow = y >> 32 & (ULong)1; - *bx++ = (ULong)(y & FFFFFFFF); - } - while(sx <= sxe); - bx = b->x; - bxe = bx + n; - if (!*bxe) { - while(--bxe > bx && !*bxe) - --n; - b->wds = n; - } - } - return q; -} - -/* sulp(x) is a version of ulp(x) that takes bc.scale into account. - - Assuming that x is finite and nonnegative (positive zero is fine - here) and x / 2^bc.scale is exactly representable as a double, - sulp(x) is equivalent to 2^bc.scale * ulp(x / 2^bc.scale). */ - -static double -sulp(U *x, BCinfo *bc) -{ - U u; - - if (bc->scale && 2*P + 1 > (int)((word0(x) & Exp_mask) >> Exp_shift)) { - /* rv/2^bc->scale is subnormal */ - word0(&u) = (P+2)*Exp_msk1; - word1(&u) = 0; - return u.d; - } - else { - assert(word0(x) || word1(x)); /* x != 0.0 */ - return ulp(x); - } -} - -/* The bigcomp function handles some hard cases for strtod, for inputs - with more than STRTOD_DIGLIM digits. It's called once an initial - estimate for the double corresponding to the input string has - already been obtained by the code in _Py_dg_strtod. - - The bigcomp function is only called after _Py_dg_strtod has found a - double value rv such that either rv or rv + 1ulp represents the - correctly rounded value corresponding to the original string. It - determines which of these two values is the correct one by - computing the decimal digits of rv + 0.5ulp and comparing them with - the corresponding digits of s0. - - In the following, write dv for the absolute value of the number represented - by the input string. - - Inputs: - - s0 points to the first significant digit of the input string. - - rv is a (possibly scaled) estimate for the closest double value to the - value represented by the original input to _Py_dg_strtod. If - bc->scale is nonzero, then rv/2^(bc->scale) is the approximation to - the input value. - - bc is a struct containing information gathered during the parsing and - estimation steps of _Py_dg_strtod. Description of fields follows: - - bc->e0 gives the exponent of the input value, such that dv = (integer - given by the bd->nd digits of s0) * 10**e0 - - bc->nd gives the total number of significant digits of s0. It will - be at least 1. - - bc->nd0 gives the number of significant digits of s0 before the - decimal separator. If there's no decimal separator, bc->nd0 == - bc->nd. - - bc->scale is the value used to scale rv to avoid doing arithmetic with - subnormal values. It's either 0 or 2*P (=106). - - Outputs: - - On successful exit, rv/2^(bc->scale) is the closest double to dv. - - Returns 0 on success, -1 on failure (e.g., due to a failed malloc call). */ - -static int -bigcomp(U *rv, const char *s0, BCinfo *bc) -{ - Bigint *b, *d; - int b2, d2, dd, i, nd, nd0, odd, p2, p5; - - nd = bc->nd; - nd0 = bc->nd0; - p5 = nd + bc->e0; - b = sd2b(rv, bc->scale, &p2); - if (b == NULL) - return -1; - - /* record whether the lsb of rv/2^(bc->scale) is odd: in the exact halfway - case, this is used for round to even. */ - odd = b->x[0] & 1; - - /* left shift b by 1 bit and or a 1 into the least significant bit; - this gives us b * 2**p2 = rv/2^(bc->scale) + 0.5 ulp. */ - b = lshift(b, 1); - if (b == NULL) - return -1; - b->x[0] |= 1; - p2--; - - p2 -= p5; - d = i2b(1); - if (d == NULL) { - Bfree(b); - return -1; - } - /* Arrange for convenient computation of quotients: - * shift left if necessary so divisor has 4 leading 0 bits. - */ - if (p5 > 0) { - d = pow5mult(d, p5); - if (d == NULL) { - Bfree(b); - return -1; - } - } - else if (p5 < 0) { - b = pow5mult(b, -p5); - if (b == NULL) { - Bfree(d); - return -1; - } - } - if (p2 > 0) { - b2 = p2; - d2 = 0; - } - else { - b2 = 0; - d2 = -p2; - } - i = dshift(d, d2); - if ((b2 += i) > 0) { - b = lshift(b, b2); - if (b == NULL) { - Bfree(d); - return -1; - } - } - if ((d2 += i) > 0) { - d = lshift(d, d2); - if (d == NULL) { - Bfree(b); - return -1; - } - } - - /* Compare s0 with b/d: set dd to -1, 0, or 1 according as s0 < b/d, s0 == - * b/d, or s0 > b/d. Here the digits of s0 are thought of as representing - * a number in the range [0.1, 1). */ - if (cmp(b, d) >= 0) - /* b/d >= 1 */ - dd = -1; - else { - i = 0; - for(;;) { - b = multadd(b, 10, 0); - if (b == NULL) { - Bfree(d); - return -1; - } - dd = s0[i < nd0 ? i : i+1] - '0' - quorem(b, d); - i++; - - if (dd) - break; - if (!b->x[0] && b->wds == 1) { - /* b/d == 0 */ - dd = i < nd; - break; - } - if (!(i < nd)) { - /* b/d != 0, but digits of s0 exhausted */ - dd = -1; - break; - } - } - } - Bfree(b); - Bfree(d); - if (dd > 0 || (dd == 0 && odd)) - dval(rv) += sulp(rv, bc); - return 0; -} - -/* Return a 'standard' NaN value. - - There are exactly two quiet NaNs that don't arise by 'quieting' signaling - NaNs (see IEEE 754-2008, section 6.2.1). If sign == 0, return the one whose - sign bit is cleared. Otherwise, return the one whose sign bit is set. -*/ - -double -_Py_dg_stdnan(int sign) -{ - U rv; - word0(&rv) = NAN_WORD0; - word1(&rv) = NAN_WORD1; - if (sign) - word0(&rv) |= Sign_bit; - return dval(&rv); -} - -/* Return positive or negative infinity, according to the given sign (0 for - * positive infinity, 1 for negative infinity). */ - -double -_Py_dg_infinity(int sign) -{ - U rv; - word0(&rv) = POSINF_WORD0; - word1(&rv) = POSINF_WORD1; - return sign ? -dval(&rv) : dval(&rv); -} - -double -_Py_dg_strtod(const char *s00, char **se) -{ - int bb2, bb5, bbe, bd2, bd5, bs2, c, dsign, e, e1, error; - int esign, i, j, k, lz, nd, nd0, odd, sign; - const char *s, *s0, *s1; - double aadj, aadj1; - U aadj2, adj, rv, rv0; - ULong y, z, abs_exp; - Long L; - BCinfo bc; - Bigint *bb = NULL, *bd = NULL, *bd0 = NULL, *bs = NULL, *delta = NULL; - size_t ndigits, fraclen; - double result; - - dval(&rv) = 0.; - - /* Start parsing. */ - c = *(s = s00); - - /* Parse optional sign, if present. */ - sign = 0; - switch (c) { - case '-': - sign = 1; - /* fall through */ - case '+': - c = *++s; - } - - /* Skip leading zeros: lz is true iff there were leading zeros. */ - s1 = s; - while (c == '0') - c = *++s; - lz = s != s1; - - /* Point s0 at the first nonzero digit (if any). fraclen will be the - number of digits between the decimal point and the end of the - digit string. ndigits will be the total number of digits ignoring - leading zeros. */ - s0 = s1 = s; - while ('0' <= c && c <= '9') - c = *++s; - ndigits = s - s1; - fraclen = 0; - - /* Parse decimal point and following digits. */ - if (c == '.') { - c = *++s; - if (!ndigits) { - s1 = s; - while (c == '0') - c = *++s; - lz = lz || s != s1; - fraclen += (s - s1); - s0 = s; - } - s1 = s; - while ('0' <= c && c <= '9') - c = *++s; - ndigits += s - s1; - fraclen += s - s1; - } - - /* Now lz is true if and only if there were leading zero digits, and - ndigits gives the total number of digits ignoring leading zeros. A - valid input must have at least one digit. */ - if (!ndigits && !lz) { - if (se) - *se = (char *)s00; - goto parse_error; - } - - /* Range check ndigits and fraclen to make sure that they, and values - computed with them, can safely fit in an int. */ - if (ndigits > MAX_DIGITS || fraclen > MAX_DIGITS) { - if (se) - *se = (char *)s00; - goto parse_error; - } - nd = (int)ndigits; - nd0 = (int)ndigits - (int)fraclen; - - /* Parse exponent. */ - e = 0; - if (c == 'e' || c == 'E') { - s00 = s; - c = *++s; - - /* Exponent sign. */ - esign = 0; - switch (c) { - case '-': - esign = 1; - /* fall through */ - case '+': - c = *++s; - } - - /* Skip zeros. lz is true iff there are leading zeros. */ - s1 = s; - while (c == '0') - c = *++s; - lz = s != s1; - - /* Get absolute value of the exponent. */ - s1 = s; - abs_exp = 0; - while ('0' <= c && c <= '9') { - abs_exp = 10*abs_exp + (c - '0'); - c = *++s; - } - - /* abs_exp will be correct modulo 2**32. But 10**9 < 2**32, so if - there are at most 9 significant exponent digits then overflow is - impossible. */ - if (s - s1 > 9 || abs_exp > MAX_ABS_EXP) - e = (int)MAX_ABS_EXP; - else - e = (int)abs_exp; - if (esign) - e = -e; - - /* A valid exponent must have at least one digit. */ - if (s == s1 && !lz) - s = s00; - } - - /* Adjust exponent to take into account position of the point. */ - e -= nd - nd0; - if (nd0 <= 0) - nd0 = nd; - - /* Finished parsing. Set se to indicate how far we parsed */ - if (se) - *se = (char *)s; - - /* If all digits were zero, exit with return value +-0.0. Otherwise, - strip trailing zeros: scan back until we hit a nonzero digit. */ - if (!nd) - goto ret; - for (i = nd; i > 0; ) { - --i; - if (s0[i < nd0 ? i : i+1] != '0') { - ++i; - break; - } - } - e += nd - i; - nd = i; - if (nd0 > nd) - nd0 = nd; - - /* Summary of parsing results. After parsing, and dealing with zero - * inputs, we have values s0, nd0, nd, e, sign, where: - * - * - s0 points to the first significant digit of the input string - * - * - nd is the total number of significant digits (here, and - * below, 'significant digits' means the set of digits of the - * significand of the input that remain after ignoring leading - * and trailing zeros). - * - * - nd0 indicates the position of the decimal point, if present; it - * satisfies 1 <= nd0 <= nd. The nd significant digits are in - * s0[0:nd0] and s0[nd0+1:nd+1] using the usual Python half-open slice - * notation. (If nd0 < nd, then s0[nd0] contains a '.' character; if - * nd0 == nd, then s0[nd0] could be any non-digit character.) - * - * - e is the adjusted exponent: the absolute value of the number - * represented by the original input string is n * 10**e, where - * n is the integer represented by the concatenation of - * s0[0:nd0] and s0[nd0+1:nd+1] - * - * - sign gives the sign of the input: 1 for negative, 0 for positive - * - * - the first and last significant digits are nonzero - */ - - /* put first DBL_DIG+1 digits into integer y and z. - * - * - y contains the value represented by the first min(9, nd) - * significant digits - * - * - if nd > 9, z contains the value represented by significant digits - * with indices in [9, min(16, nd)). So y * 10**(min(16, nd) - 9) + z - * gives the value represented by the first min(16, nd) sig. digits. - */ - - bc.e0 = e1 = e; - y = z = 0; - for (i = 0; i < nd; i++) { - if (i < 9) - y = 10*y + s0[i < nd0 ? i : i+1] - '0'; - else if (i < DBL_DIG+1) - z = 10*z + s0[i < nd0 ? i : i+1] - '0'; - else - break; - } - - k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1; - dval(&rv) = y; - if (k > 9) { - dval(&rv) = tens[k - 9] * dval(&rv) + z; - } - if (nd <= DBL_DIG - && Flt_Rounds == 1 - ) { - if (!e) - goto ret; - if (e > 0) { - if (e <= Ten_pmax) { - dval(&rv) *= tens[e]; - goto ret; - } - i = DBL_DIG - nd; - if (e <= Ten_pmax + i) { - /* A fancier test would sometimes let us do - * this for larger i values. - */ - e -= i; - dval(&rv) *= tens[i]; - dval(&rv) *= tens[e]; - goto ret; - } - } - else if (e >= -Ten_pmax) { - dval(&rv) /= tens[-e]; - goto ret; - } - } - e1 += nd - k; - - bc.scale = 0; - - /* Get starting approximation = rv * 10**e1 */ - - if (e1 > 0) { - if ((i = e1 & 15)) - dval(&rv) *= tens[i]; - if (e1 &= ~15) { - if (e1 > DBL_MAX_10_EXP) - goto ovfl; - e1 >>= 4; - for(j = 0; e1 > 1; j++, e1 >>= 1) - if (e1 & 1) - dval(&rv) *= bigtens[j]; - /* The last multiplication could overflow. */ - word0(&rv) -= P*Exp_msk1; - dval(&rv) *= bigtens[j]; - if ((z = word0(&rv) & Exp_mask) - > Exp_msk1*(DBL_MAX_EXP+Bias-P)) - goto ovfl; - if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) { - /* set to largest number */ - /* (Can't trust DBL_MAX) */ - word0(&rv) = Big0; - word1(&rv) = Big1; - } - else - word0(&rv) += P*Exp_msk1; - } - } - else if (e1 < 0) { - /* The input decimal value lies in [10**e1, 10**(e1+16)). - - If e1 <= -512, underflow immediately. - If e1 <= -256, set bc.scale to 2*P. - - So for input value < 1e-256, bc.scale is always set; - for input value >= 1e-240, bc.scale is never set. - For input values in [1e-256, 1e-240), bc.scale may or may - not be set. */ - - e1 = -e1; - if ((i = e1 & 15)) - dval(&rv) /= tens[i]; - if (e1 >>= 4) { - if (e1 >= 1 << n_bigtens) - goto undfl; - if (e1 & Scale_Bit) - bc.scale = 2*P; - for(j = 0; e1 > 0; j++, e1 >>= 1) - if (e1 & 1) - dval(&rv) *= tinytens[j]; - if (bc.scale && (j = 2*P + 1 - ((word0(&rv) & Exp_mask) - >> Exp_shift)) > 0) { - /* scaled rv is denormal; clear j low bits */ - if (j >= 32) { - word1(&rv) = 0; - if (j >= 53) - word0(&rv) = (P+2)*Exp_msk1; - else - word0(&rv) &= 0xffffffff << (j-32); - } - else - word1(&rv) &= 0xffffffff << j; - } - if (!dval(&rv)) - goto undfl; - } - } - - /* Now the hard part -- adjusting rv to the correct value.*/ - - /* Put digits into bd: true value = bd * 10^e */ - - bc.nd = nd; - bc.nd0 = nd0; /* Only needed if nd > STRTOD_DIGLIM, but done here */ - /* to silence an erroneous warning about bc.nd0 */ - /* possibly not being initialized. */ - if (nd > STRTOD_DIGLIM) { - /* ASSERT(STRTOD_DIGLIM >= 18); 18 == one more than the */ - /* minimum number of decimal digits to distinguish double values */ - /* in IEEE arithmetic. */ - - /* Truncate input to 18 significant digits, then discard any trailing - zeros on the result by updating nd, nd0, e and y suitably. (There's - no need to update z; it's not reused beyond this point.) */ - for (i = 18; i > 0; ) { - /* scan back until we hit a nonzero digit. significant digit 'i' - is s0[i] if i < nd0, s0[i+1] if i >= nd0. */ - --i; - if (s0[i < nd0 ? i : i+1] != '0') { - ++i; - break; - } - } - e += nd - i; - nd = i; - if (nd0 > nd) - nd0 = nd; - if (nd < 9) { /* must recompute y */ - y = 0; - for(i = 0; i < nd0; ++i) - y = 10*y + s0[i] - '0'; - for(; i < nd; ++i) - y = 10*y + s0[i+1] - '0'; - } - } - bd0 = s2b(s0, nd0, nd, y); - if (bd0 == NULL) - goto failed_malloc; - - /* Notation for the comments below. Write: - - - dv for the absolute value of the number represented by the original - decimal input string. - - - if we've truncated dv, write tdv for the truncated value. - Otherwise, set tdv == dv. - - - srv for the quantity rv/2^bc.scale; so srv is the current binary - approximation to tdv (and dv). It should be exactly representable - in an IEEE 754 double. - */ - - for(;;) { - - /* This is the main correction loop for _Py_dg_strtod. - - We've got a decimal value tdv, and a floating-point approximation - srv=rv/2^bc.scale to tdv. The aim is to determine whether srv is - close enough (i.e., within 0.5 ulps) to tdv, and to compute a new - approximation if not. - - To determine whether srv is close enough to tdv, compute integers - bd, bb and bs proportional to tdv, srv and 0.5 ulp(srv) - respectively, and then use integer arithmetic to determine whether - |tdv - srv| is less than, equal to, or greater than 0.5 ulp(srv). - */ - - bd = Balloc(bd0->k); - if (bd == NULL) { - goto failed_malloc; - } - Bcopy(bd, bd0); - bb = sd2b(&rv, bc.scale, &bbe); /* srv = bb * 2^bbe */ - if (bb == NULL) { - goto failed_malloc; - } - /* Record whether lsb of bb is odd, in case we need this - for the round-to-even step later. */ - odd = bb->x[0] & 1; - - /* tdv = bd * 10**e; srv = bb * 2**bbe */ - bs = i2b(1); - if (bs == NULL) { - goto failed_malloc; - } - - if (e >= 0) { - bb2 = bb5 = 0; - bd2 = bd5 = e; - } - else { - bb2 = bb5 = -e; - bd2 = bd5 = 0; - } - if (bbe >= 0) - bb2 += bbe; - else - bd2 -= bbe; - bs2 = bb2; - bb2++; - bd2++; - - /* At this stage bd5 - bb5 == e == bd2 - bb2 + bbe, bb2 - bs2 == 1, - and bs == 1, so: - - tdv == bd * 10**e = bd * 2**(bbe - bb2 + bd2) * 5**(bd5 - bb5) - srv == bb * 2**bbe = bb * 2**(bbe - bb2 + bb2) - 0.5 ulp(srv) == 2**(bbe-1) = bs * 2**(bbe - bb2 + bs2) - - It follows that: - - M * tdv = bd * 2**bd2 * 5**bd5 - M * srv = bb * 2**bb2 * 5**bb5 - M * 0.5 ulp(srv) = bs * 2**bs2 * 5**bb5 - - for some constant M. (Actually, M == 2**(bb2 - bbe) * 5**bb5, but - this fact is not needed below.) - */ - - /* Remove factor of 2**i, where i = min(bb2, bd2, bs2). */ - i = bb2 < bd2 ? bb2 : bd2; - if (i > bs2) - i = bs2; - if (i > 0) { - bb2 -= i; - bd2 -= i; - bs2 -= i; - } - - /* Scale bb, bd, bs by the appropriate powers of 2 and 5. */ - if (bb5 > 0) { - bs = pow5mult(bs, bb5); - if (bs == NULL) { - goto failed_malloc; - } - Bigint *bb1 = mult(bs, bb); - Bfree(bb); - bb = bb1; - if (bb == NULL) { - goto failed_malloc; - } - } - if (bb2 > 0) { - bb = lshift(bb, bb2); - if (bb == NULL) { - goto failed_malloc; - } - } - if (bd5 > 0) { - bd = pow5mult(bd, bd5); - if (bd == NULL) { - goto failed_malloc; - } - } - if (bd2 > 0) { - bd = lshift(bd, bd2); - if (bd == NULL) { - goto failed_malloc; - } - } - if (bs2 > 0) { - bs = lshift(bs, bs2); - if (bs == NULL) { - goto failed_malloc; - } - } - - /* Now bd, bb and bs are scaled versions of tdv, srv and 0.5 ulp(srv), - respectively. Compute the difference |tdv - srv|, and compare - with 0.5 ulp(srv). */ - - delta = diff(bb, bd); - if (delta == NULL) { - goto failed_malloc; - } - dsign = delta->sign; - delta->sign = 0; - i = cmp(delta, bs); - if (bc.nd > nd && i <= 0) { - if (dsign) - break; /* Must use bigcomp(). */ - - /* Here rv overestimates the truncated decimal value by at most - 0.5 ulp(rv). Hence rv either overestimates the true decimal - value by <= 0.5 ulp(rv), or underestimates it by some small - amount (< 0.1 ulp(rv)); either way, rv is within 0.5 ulps of - the true decimal value, so it's possible to exit. - - Exception: if scaled rv is a normal exact power of 2, but not - DBL_MIN, then rv - 0.5 ulp(rv) takes us all the way down to the - next double, so the correctly rounded result is either rv - 0.5 - ulp(rv) or rv; in this case, use bigcomp to distinguish. */ - - if (!word1(&rv) && !(word0(&rv) & Bndry_mask)) { - /* rv can't be 0, since it's an overestimate for some - nonzero value. So rv is a normal power of 2. */ - j = (int)(word0(&rv) & Exp_mask) >> Exp_shift; - /* rv / 2^bc.scale = 2^(j - 1023 - bc.scale); use bigcomp if - rv / 2^bc.scale >= 2^-1021. */ - if (j - bc.scale >= 2) { - dval(&rv) -= 0.5 * sulp(&rv, &bc); - break; /* Use bigcomp. */ - } - } - - { - bc.nd = nd; - i = -1; /* Discarded digits make delta smaller. */ - } - } - - if (i < 0) { - /* Error is less than half an ulp -- check for - * special case of mantissa a power of two. - */ - if (dsign || word1(&rv) || word0(&rv) & Bndry_mask - || (word0(&rv) & Exp_mask) <= (2*P+1)*Exp_msk1 - ) { - break; - } - if (!delta->x[0] && delta->wds <= 1) { - /* exact result */ - break; - } - delta = lshift(delta,Log2P); - if (delta == NULL) { - goto failed_malloc; - } - if (cmp(delta, bs) > 0) - goto drop_down; - break; - } - if (i == 0) { - /* exactly half-way between */ - if (dsign) { - if ((word0(&rv) & Bndry_mask1) == Bndry_mask1 - && word1(&rv) == ( - (bc.scale && - (y = word0(&rv) & Exp_mask) <= 2*P*Exp_msk1) ? - (0xffffffff & (0xffffffff << (2*P+1-(y>>Exp_shift)))) : - 0xffffffff)) { - /*boundary case -- increment exponent*/ - word0(&rv) = (word0(&rv) & Exp_mask) - + Exp_msk1 - ; - word1(&rv) = 0; - /* dsign = 0; */ - break; - } - } - else if (!(word0(&rv) & Bndry_mask) && !word1(&rv)) { - drop_down: - /* boundary case -- decrement exponent */ - if (bc.scale) { - L = word0(&rv) & Exp_mask; - if (L <= (2*P+1)*Exp_msk1) { - if (L > (P+2)*Exp_msk1) - /* round even ==> */ - /* accept rv */ - break; - /* rv = smallest denormal */ - if (bc.nd > nd) - break; - goto undfl; - } - } - L = (word0(&rv) & Exp_mask) - Exp_msk1; - word0(&rv) = L | Bndry_mask1; - word1(&rv) = 0xffffffff; - break; - } - if (!odd) - break; - if (dsign) - dval(&rv) += sulp(&rv, &bc); - else { - dval(&rv) -= sulp(&rv, &bc); - if (!dval(&rv)) { - if (bc.nd >nd) - break; - goto undfl; - } - } - /* dsign = 1 - dsign; */ - break; - } - if ((aadj = ratio(delta, bs)) <= 2.) { - if (dsign) - aadj = aadj1 = 1.; - else if (word1(&rv) || word0(&rv) & Bndry_mask) { - if (word1(&rv) == Tiny1 && !word0(&rv)) { - if (bc.nd >nd) - break; - goto undfl; - } - aadj = 1.; - aadj1 = -1.; - } - else { - /* special case -- power of FLT_RADIX to be */ - /* rounded down... */ - - if (aadj < 2./FLT_RADIX) - aadj = 1./FLT_RADIX; - else - aadj *= 0.5; - aadj1 = -aadj; - } - } - else { - aadj *= 0.5; - aadj1 = dsign ? aadj : -aadj; - if (Flt_Rounds == 0) - aadj1 += 0.5; - } - y = word0(&rv) & Exp_mask; - - /* Check for overflow */ - - if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) { - dval(&rv0) = dval(&rv); - word0(&rv) -= P*Exp_msk1; - adj.d = aadj1 * ulp(&rv); - dval(&rv) += adj.d; - if ((word0(&rv) & Exp_mask) >= - Exp_msk1*(DBL_MAX_EXP+Bias-P)) { - if (word0(&rv0) == Big0 && word1(&rv0) == Big1) { - goto ovfl; - } - word0(&rv) = Big0; - word1(&rv) = Big1; - goto cont; - } - else - word0(&rv) += P*Exp_msk1; - } - else { - if (bc.scale && y <= 2*P*Exp_msk1) { - if (aadj <= 0x7fffffff) { - if ((z = (ULong)aadj) <= 0) - z = 1; - aadj = z; - aadj1 = dsign ? aadj : -aadj; - } - dval(&aadj2) = aadj1; - word0(&aadj2) += (2*P+1)*Exp_msk1 - y; - aadj1 = dval(&aadj2); - } - adj.d = aadj1 * ulp(&rv); - dval(&rv) += adj.d; - } - z = word0(&rv) & Exp_mask; - if (bc.nd == nd) { - if (!bc.scale) - if (y == z) { - /* Can we stop now? */ - L = (Long)aadj; - aadj -= L; - /* The tolerances below are conservative. */ - if (dsign || word1(&rv) || word0(&rv) & Bndry_mask) { - if (aadj < .4999999 || aadj > .5000001) - break; - } - else if (aadj < .4999999/FLT_RADIX) - break; - } - } - cont: - Bfree(bb); bb = NULL; - Bfree(bd); bd = NULL; - Bfree(bs); bs = NULL; - Bfree(delta); delta = NULL; - } - if (bc.nd > nd) { - error = bigcomp(&rv, s0, &bc); - if (error) - goto failed_malloc; - } - - if (bc.scale) { - word0(&rv0) = Exp_1 - 2*P*Exp_msk1; - word1(&rv0) = 0; - dval(&rv) *= dval(&rv0); - } - - ret: - result = sign ? -dval(&rv) : dval(&rv); - goto done; - - parse_error: - result = 0.0; - goto done; - - failed_malloc: - errno = ENOMEM; - result = -1.0; - goto done; - - undfl: - result = sign ? -0.0 : 0.0; - goto done; - - ovfl: - errno = ERANGE; - /* Can't trust HUGE_VAL */ - word0(&rv) = Exp_mask; - word1(&rv) = 0; - result = sign ? -dval(&rv) : dval(&rv); - goto done; - - done: - Bfree(bb); - Bfree(bd); - Bfree(bs); - Bfree(bd0); - Bfree(delta); - return result; - -} - -static char * -rv_alloc(int i) -{ - int j, k, *r; - - j = sizeof(ULong); - for(k = 0; - sizeof(Bigint) - sizeof(ULong) - sizeof(int) + j <= (unsigned)i; - j <<= 1) - k++; - r = (int*)Balloc(k); - if (r == NULL) - return NULL; - *r = k; - return (char *)(r+1); -} - -static char * -nrv_alloc(const char *s, char **rve, int n) -{ - char *rv, *t; - - rv = rv_alloc(n); - if (rv == NULL) - return NULL; - t = rv; - while((*t = *s++)) t++; - if (rve) - *rve = t; - return rv; -} - -/* freedtoa(s) must be used to free values s returned by dtoa - * when MULTIPLE_THREADS is #defined. It should be used in all cases, - * but for consistency with earlier versions of dtoa, it is optional - * when MULTIPLE_THREADS is not defined. - */ - -void -_Py_dg_freedtoa(char *s) -{ - Bigint *b = (Bigint *)((int *)s - 1); - b->maxwds = 1 << (b->k = *(int*)b); - Bfree(b); -} - -/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string. - * - * Inspired by "How to Print Floating-Point Numbers Accurately" by - * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 112-126]. - * - * Modifications: - * 1. Rather than iterating, we use a simple numeric overestimate - * to determine k = floor(log10(d)). We scale relevant - * quantities using O(log2(k)) rather than O(k) multiplications. - * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't - * try to generate digits strictly left to right. Instead, we - * compute with fewer bits and propagate the carry if necessary - * when rounding the final digit up. This is often faster. - * 3. Under the assumption that input will be rounded nearest, - * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22. - * That is, we allow equality in stopping tests when the - * round-nearest rule will give the same floating-point value - * as would satisfaction of the stopping test with strict - * inequality. - * 4. We remove common factors of powers of 2 from relevant - * quantities. - * 5. When converting floating-point integers less than 1e16, - * we use floating-point arithmetic rather than resorting - * to multiple-precision integers. - * 6. When asked to produce fewer than 15 digits, we first try - * to get by with floating-point arithmetic; we resort to - * multiple-precision integer arithmetic only if we cannot - * guarantee that the floating-point calculation has given - * the correctly rounded result. For k requested digits and - * "uniformly" distributed input, the probability is - * something like 10^(k-15) that we must resort to the Long - * calculation. - */ - -/* Additional notes (METD): (1) returns NULL on failure. (2) to avoid memory - leakage, a successful call to _Py_dg_dtoa should always be matched by a - call to _Py_dg_freedtoa. */ - -char * -_Py_dg_dtoa(double dd, int mode, int ndigits, - int *decpt, int *sign, char **rve) -{ - /* Arguments ndigits, decpt, sign are similar to those - of ecvt and fcvt; trailing zeros are suppressed from - the returned string. If not null, *rve is set to point - to the end of the return value. If d is +-Infinity or NaN, - then *decpt is set to 9999. - - mode: - 0 ==> shortest string that yields d when read in - and rounded to nearest. - 1 ==> like 0, but with Steele & White stopping rule; - e.g. with IEEE P754 arithmetic , mode 0 gives - 1e23 whereas mode 1 gives 9.999999999999999e22. - 2 ==> max(1,ndigits) significant digits. This gives a - return value similar to that of ecvt, except - that trailing zeros are suppressed. - 3 ==> through ndigits past the decimal point. This - gives a return value similar to that from fcvt, - except that trailing zeros are suppressed, and - ndigits can be negative. - 4,5 ==> similar to 2 and 3, respectively, but (in - round-nearest mode) with the tests of mode 0 to - possibly return a shorter string that rounds to d. - With IEEE arithmetic and compilation with - -DHonor_FLT_ROUNDS, modes 4 and 5 behave the same - as modes 2 and 3 when FLT_ROUNDS != 1. - 6-9 ==> Debugging modes similar to mode - 4: don't try - fast floating-point estimate (if applicable). - - Values of mode other than 0-9 are treated as mode 0. - - Sufficient space is allocated to the return value - to hold the suppressed trailing zeros. - */ - - int bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1, - j, j1, k, k0, k_check, leftright, m2, m5, s2, s5, - spec_case, try_quick; - Long L; - int denorm; - ULong x; - Bigint *b, *b1, *delta, *mlo, *mhi, *S; - U d2, eps, u; - double ds; - char *s, *s0; - - /* set pointers to NULL, to silence gcc compiler warnings and make - cleanup easier on error */ - mlo = mhi = S = 0; - s0 = 0; - - u.d = dd; - if (word0(&u) & Sign_bit) { - /* set sign for everything, including 0's and NaNs */ - *sign = 1; - word0(&u) &= ~Sign_bit; /* clear sign bit */ - } - else - *sign = 0; - - /* quick return for Infinities, NaNs and zeros */ - if ((word0(&u) & Exp_mask) == Exp_mask) - { - /* Infinity or NaN */ - *decpt = 9999; - if (!word1(&u) && !(word0(&u) & 0xfffff)) - return nrv_alloc("Infinity", rve, 8); - return nrv_alloc("NaN", rve, 3); - } - if (!dval(&u)) { - *decpt = 1; - return nrv_alloc("0", rve, 1); - } - - /* compute k = floor(log10(d)). The computation may leave k - one too large, but should never leave k too small. */ - b = d2b(&u, &be, &bbits); - if (b == NULL) - goto failed_malloc; - if ((i = (int)(word0(&u) >> Exp_shift1 & (Exp_mask>>Exp_shift1)))) { - dval(&d2) = dval(&u); - word0(&d2) &= Frac_mask1; - word0(&d2) |= Exp_11; - - /* log(x) ~=~ log(1.5) + (x-1.5)/1.5 - * log10(x) = log(x) / log(10) - * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10)) - * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2) - * - * This suggests computing an approximation k to log10(d) by - * - * k = (i - Bias)*0.301029995663981 - * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 ); - * - * We want k to be too large rather than too small. - * The error in the first-order Taylor series approximation - * is in our favor, so we just round up the constant enough - * to compensate for any error in the multiplication of - * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077, - * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14, - * adding 1e-13 to the constant term more than suffices. - * Hence we adjust the constant term to 0.1760912590558. - * (We could get a more accurate k by invoking log10, - * but this is probably not worthwhile.) - */ - - i -= Bias; - denorm = 0; - } - else { - /* d is denormalized */ - - i = bbits + be + (Bias + (P-1) - 1); - x = i > 32 ? word0(&u) << (64 - i) | word1(&u) >> (i - 32) - : word1(&u) << (32 - i); - dval(&d2) = x; - word0(&d2) -= 31*Exp_msk1; /* adjust exponent */ - i -= (Bias + (P-1) - 1) + 1; - denorm = 1; - } - ds = (dval(&d2)-1.5)*0.289529654602168 + 0.1760912590558 + - i*0.301029995663981; - k = (int)ds; - if (ds < 0. && ds != k) - k--; /* want k = floor(ds) */ - k_check = 1; - if (k >= 0 && k <= Ten_pmax) { - if (dval(&u) < tens[k]) - k--; - k_check = 0; - } - j = bbits - i - 1; - if (j >= 0) { - b2 = 0; - s2 = j; - } - else { - b2 = -j; - s2 = 0; - } - if (k >= 0) { - b5 = 0; - s5 = k; - s2 += k; - } - else { - b2 -= k; - b5 = -k; - s5 = 0; - } - if (mode < 0 || mode > 9) - mode = 0; - - try_quick = 1; - - if (mode > 5) { - mode -= 4; - try_quick = 0; - } - leftright = 1; - ilim = ilim1 = -1; /* Values for cases 0 and 1; done here to */ - /* silence erroneous "gcc -Wall" warning. */ - switch(mode) { - case 0: - case 1: - i = 18; - ndigits = 0; - break; - case 2: - leftright = 0; - /* fall through */ - case 4: - if (ndigits <= 0) - ndigits = 1; - ilim = ilim1 = i = ndigits; - break; - case 3: - leftright = 0; - /* fall through */ - case 5: - i = ndigits + k + 1; - ilim = i; - ilim1 = i - 1; - if (i <= 0) - i = 1; - } - s0 = rv_alloc(i); - if (s0 == NULL) - goto failed_malloc; - s = s0; - - - if (ilim >= 0 && ilim <= Quick_max && try_quick) { - - /* Try to get by with floating-point arithmetic. */ - - i = 0; - dval(&d2) = dval(&u); - k0 = k; - ilim0 = ilim; - ieps = 2; /* conservative */ - if (k > 0) { - ds = tens[k&0xf]; - j = k >> 4; - if (j & Bletch) { - /* prevent overflows */ - j &= Bletch - 1; - dval(&u) /= bigtens[n_bigtens-1]; - ieps++; - } - for(; j; j >>= 1, i++) - if (j & 1) { - ieps++; - ds *= bigtens[i]; - } - dval(&u) /= ds; - } - else if ((j1 = -k)) { - dval(&u) *= tens[j1 & 0xf]; - for(j = j1 >> 4; j; j >>= 1, i++) - if (j & 1) { - ieps++; - dval(&u) *= bigtens[i]; - } - } - if (k_check && dval(&u) < 1. && ilim > 0) { - if (ilim1 <= 0) - goto fast_failed; - ilim = ilim1; - k--; - dval(&u) *= 10.; - ieps++; - } - dval(&eps) = ieps*dval(&u) + 7.; - word0(&eps) -= (P-1)*Exp_msk1; - if (ilim == 0) { - S = mhi = 0; - dval(&u) -= 5.; - if (dval(&u) > dval(&eps)) - goto one_digit; - if (dval(&u) < -dval(&eps)) - goto no_digits; - goto fast_failed; - } - if (leftright) { - /* Use Steele & White method of only - * generating digits needed. - */ - dval(&eps) = 0.5/tens[ilim-1] - dval(&eps); - for(i = 0;;) { - L = (Long)dval(&u); - dval(&u) -= L; - *s++ = '0' + (int)L; - if (dval(&u) < dval(&eps)) - goto ret1; - if (1. - dval(&u) < dval(&eps)) - goto bump_up; - if (++i >= ilim) - break; - dval(&eps) *= 10.; - dval(&u) *= 10.; - } - } - else { - /* Generate ilim digits, then fix them up. */ - dval(&eps) *= tens[ilim-1]; - for(i = 1;; i++, dval(&u) *= 10.) { - L = (Long)(dval(&u)); - if (!(dval(&u) -= L)) - ilim = i; - *s++ = '0' + (int)L; - if (i == ilim) { - if (dval(&u) > 0.5 + dval(&eps)) - goto bump_up; - else if (dval(&u) < 0.5 - dval(&eps)) { - while(*--s == '0'); - s++; - goto ret1; - } - break; - } - } - } - fast_failed: - s = s0; - dval(&u) = dval(&d2); - k = k0; - ilim = ilim0; - } - - /* Do we have a "small" integer? */ - - if (be >= 0 && k <= Int_max) { - /* Yes. */ - ds = tens[k]; - if (ndigits < 0 && ilim <= 0) { - S = mhi = 0; - if (ilim < 0 || dval(&u) <= 5*ds) - goto no_digits; - goto one_digit; - } - for(i = 1;; i++, dval(&u) *= 10.) { - L = (Long)(dval(&u) / ds); - dval(&u) -= L*ds; - *s++ = '0' + (int)L; - if (!dval(&u)) { - break; - } - if (i == ilim) { - dval(&u) += dval(&u); - if (dval(&u) > ds || (dval(&u) == ds && L & 1)) { - bump_up: - while(*--s == '9') - if (s == s0) { - k++; - *s = '0'; - break; - } - ++*s++; - } - else { - /* Strip trailing zeros. This branch was missing from the - original dtoa.c, leading to surplus trailing zeros in - some cases. See bugs.python.org/issue40780. */ - while (s > s0 && s[-1] == '0') { - --s; - } - } - break; - } - } - goto ret1; - } - - m2 = b2; - m5 = b5; - if (leftright) { - i = - denorm ? be + (Bias + (P-1) - 1 + 1) : - 1 + P - bbits; - b2 += i; - s2 += i; - mhi = i2b(1); - if (mhi == NULL) - goto failed_malloc; - } - if (m2 > 0 && s2 > 0) { - i = m2 < s2 ? m2 : s2; - b2 -= i; - m2 -= i; - s2 -= i; - } - if (b5 > 0) { - if (leftright) { - if (m5 > 0) { - mhi = pow5mult(mhi, m5); - if (mhi == NULL) - goto failed_malloc; - b1 = mult(mhi, b); - Bfree(b); - b = b1; - if (b == NULL) - goto failed_malloc; - } - if ((j = b5 - m5)) { - b = pow5mult(b, j); - if (b == NULL) - goto failed_malloc; - } - } - else { - b = pow5mult(b, b5); - if (b == NULL) - goto failed_malloc; - } - } - S = i2b(1); - if (S == NULL) - goto failed_malloc; - if (s5 > 0) { - S = pow5mult(S, s5); - if (S == NULL) - goto failed_malloc; - } - - /* Check for special case that d is a normalized power of 2. */ - - spec_case = 0; - if ((mode < 2 || leftright) - ) { - if (!word1(&u) && !(word0(&u) & Bndry_mask) - && word0(&u) & (Exp_mask & ~Exp_msk1) - ) { - /* The special case */ - b2 += Log2P; - s2 += Log2P; - spec_case = 1; - } - } - - /* Arrange for convenient computation of quotients: - * shift left if necessary so divisor has 4 leading 0 bits. - * - * Perhaps we should just compute leading 28 bits of S once - * and for all and pass them and a shift to quorem, so it - * can do shifts and ors to compute the numerator for q. - */ -#define iInc 28 - i = dshift(S, s2); - b2 += i; - m2 += i; - s2 += i; - if (b2 > 0) { - b = lshift(b, b2); - if (b == NULL) - goto failed_malloc; - } - if (s2 > 0) { - S = lshift(S, s2); - if (S == NULL) - goto failed_malloc; - } - if (k_check) { - if (cmp(b,S) < 0) { - k--; - b = multadd(b, 10, 0); /* we botched the k estimate */ - if (b == NULL) - goto failed_malloc; - if (leftright) { - mhi = multadd(mhi, 10, 0); - if (mhi == NULL) - goto failed_malloc; - } - ilim = ilim1; - } - } - if (ilim <= 0 && (mode == 3 || mode == 5)) { - if (ilim < 0) { - /* no digits, fcvt style */ - no_digits: - k = -1 - ndigits; - goto ret; - } - else { - S = multadd(S, 5, 0); - if (S == NULL) - goto failed_malloc; - if (cmp(b, S) <= 0) - goto no_digits; - } - one_digit: - *s++ = '1'; - k++; - goto ret; - } - if (leftright) { - if (m2 > 0) { - mhi = lshift(mhi, m2); - if (mhi == NULL) - goto failed_malloc; - } - - /* Compute mlo -- check for special case - * that d is a normalized power of 2. - */ - - mlo = mhi; - if (spec_case) { - mhi = Balloc(mhi->k); - if (mhi == NULL) - goto failed_malloc; - Bcopy(mhi, mlo); - mhi = lshift(mhi, Log2P); - if (mhi == NULL) - goto failed_malloc; - } - - for(i = 1;;i++) { - dig = quorem(b,S) + '0'; - /* Do we yet have the shortest decimal string - * that will round to d? - */ - j = cmp(b, mlo); - delta = diff(S, mhi); - if (delta == NULL) - goto failed_malloc; - j1 = delta->sign ? 1 : cmp(b, delta); - Bfree(delta); - if (j1 == 0 && mode != 1 && !(word1(&u) & 1) - ) { - if (dig == '9') - goto round_9_up; - if (j > 0) - dig++; - *s++ = dig; - goto ret; - } - if (j < 0 || (j == 0 && mode != 1 - && !(word1(&u) & 1) - )) { - if (!b->x[0] && b->wds <= 1) { - goto accept_dig; - } - if (j1 > 0) { - b = lshift(b, 1); - if (b == NULL) - goto failed_malloc; - j1 = cmp(b, S); - if ((j1 > 0 || (j1 == 0 && dig & 1)) - && dig++ == '9') - goto round_9_up; - } - accept_dig: - *s++ = dig; - goto ret; - } - if (j1 > 0) { - if (dig == '9') { /* possible if i == 1 */ - round_9_up: - *s++ = '9'; - goto roundoff; - } - *s++ = dig + 1; - goto ret; - } - *s++ = dig; - if (i == ilim) - break; - b = multadd(b, 10, 0); - if (b == NULL) - goto failed_malloc; - if (mlo == mhi) { - mlo = mhi = multadd(mhi, 10, 0); - if (mlo == NULL) - goto failed_malloc; - } - else { - mlo = multadd(mlo, 10, 0); - if (mlo == NULL) - goto failed_malloc; - mhi = multadd(mhi, 10, 0); - if (mhi == NULL) - goto failed_malloc; - } - } - } - else - for(i = 1;; i++) { - *s++ = dig = quorem(b,S) + '0'; - if (!b->x[0] && b->wds <= 1) { - goto ret; - } - if (i >= ilim) - break; - b = multadd(b, 10, 0); - if (b == NULL) - goto failed_malloc; - } - - /* Round off last digit */ - - b = lshift(b, 1); - if (b == NULL) - goto failed_malloc; - j = cmp(b, S); - if (j > 0 || (j == 0 && dig & 1)) { - roundoff: - while(*--s == '9') - if (s == s0) { - k++; - *s++ = '1'; - goto ret; - } - ++*s++; - } - else { - while(*--s == '0'); - s++; - } - ret: - Bfree(S); - if (mhi) { - if (mlo && mlo != mhi) - Bfree(mlo); - Bfree(mhi); - } - ret1: - Bfree(b); - *s = 0; - *decpt = k + 1; - if (rve) - *rve = s; - return s0; - failed_malloc: - if (S) - Bfree(S); - if (mlo && mlo != mhi) - Bfree(mlo); - if (mhi) - Bfree(mhi); - if (b) - Bfree(b); - if (s0) - _Py_dg_freedtoa(s0); - return NULL; -} -#ifdef __cplusplus -} -#endif - -#endif /* PY_NO_SHORT_FLOAT_REPR */ diff --git a/contrib/tools/python3/src/Python/dynamic_annotations.c b/contrib/tools/python3/src/Python/dynamic_annotations.c deleted file mode 100644 index 7febaa09df1..00000000000 --- a/contrib/tools/python3/src/Python/dynamic_annotations.c +++ /dev/null @@ -1,154 +0,0 @@ -/* Copyright (c) 2008-2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * --- - * Author: Kostya Serebryany - */ - -#ifdef _MSC_VER -# include <windows.h> -#endif - -#ifdef __cplusplus -# error "This file should be built as pure C to avoid name mangling" -#endif - -#include <stdlib.h> -#include <string.h> - -#include "dynamic_annotations.h" - -/* Each function is empty and called (via a macro) only in debug mode. - The arguments are captured by dynamic tools at runtime. */ - -#if DYNAMIC_ANNOTATIONS_ENABLED == 1 - -void AnnotateRWLockCreate(const char *file, int line, - const volatile void *lock){} -void AnnotateRWLockDestroy(const char *file, int line, - const volatile void *lock){} -void AnnotateRWLockAcquired(const char *file, int line, - const volatile void *lock, long is_w){} -void AnnotateRWLockReleased(const char *file, int line, - const volatile void *lock, long is_w){} -void AnnotateBarrierInit(const char *file, int line, - const volatile void *barrier, long count, - long reinitialization_allowed) {} -void AnnotateBarrierWaitBefore(const char *file, int line, - const volatile void *barrier) {} -void AnnotateBarrierWaitAfter(const char *file, int line, - const volatile void *barrier) {} -void AnnotateBarrierDestroy(const char *file, int line, - const volatile void *barrier) {} - -void AnnotateCondVarWait(const char *file, int line, - const volatile void *cv, - const volatile void *lock){} -void AnnotateCondVarSignal(const char *file, int line, - const volatile void *cv){} -void AnnotateCondVarSignalAll(const char *file, int line, - const volatile void *cv){} -void AnnotatePublishMemoryRange(const char *file, int line, - const volatile void *address, - long size){} -void AnnotateUnpublishMemoryRange(const char *file, int line, - const volatile void *address, - long size){} -void AnnotatePCQCreate(const char *file, int line, - const volatile void *pcq){} -void AnnotatePCQDestroy(const char *file, int line, - const volatile void *pcq){} -void AnnotatePCQPut(const char *file, int line, - const volatile void *pcq){} -void AnnotatePCQGet(const char *file, int line, - const volatile void *pcq){} -void AnnotateNewMemory(const char *file, int line, - const volatile void *mem, - long size){} -void AnnotateExpectRace(const char *file, int line, - const volatile void *mem, - const char *description){} -void AnnotateBenignRace(const char *file, int line, - const volatile void *mem, - const char *description){} -void AnnotateBenignRaceSized(const char *file, int line, - const volatile void *mem, - long size, - const char *description) {} -void AnnotateMutexIsUsedAsCondVar(const char *file, int line, - const volatile void *mu){} -void AnnotateTraceMemory(const char *file, int line, - const volatile void *arg){} -void AnnotateThreadName(const char *file, int line, - const char *name){} -void AnnotateIgnoreReadsBegin(const char *file, int line){} -void AnnotateIgnoreReadsEnd(const char *file, int line){} -void AnnotateIgnoreWritesBegin(const char *file, int line){} -void AnnotateIgnoreWritesEnd(const char *file, int line){} -void AnnotateIgnoreSyncBegin(const char *file, int line){} -void AnnotateIgnoreSyncEnd(const char *file, int line){} -void AnnotateEnableRaceDetection(const char *file, int line, int enable){} -void AnnotateNoOp(const char *file, int line, - const volatile void *arg){} -void AnnotateFlushState(const char *file, int line){} - -static int GetRunningOnValgrind(void) { -#ifdef RUNNING_ON_VALGRIND - if (RUNNING_ON_VALGRIND) return 1; -#endif - -#ifndef _MSC_VER - const char *running_on_valgrind_str = getenv("RUNNING_ON_VALGRIND"); - if (running_on_valgrind_str) { - return strcmp(running_on_valgrind_str, "0") != 0; - } -#else - /* Visual Studio issues warnings if we use getenv, - * so we use GetEnvironmentVariableA instead. - */ - char value[100] = "1"; - int res = GetEnvironmentVariableA("RUNNING_ON_VALGRIND", - value, sizeof(value)); - /* value will remain "1" if res == 0 or res >= sizeof(value). The latter - * can happen only if the given value is long, in this case it can't be "0". - */ - if (res > 0 && !strcmp(value, "0")) - return 1; -#endif - return 0; -} - -/* See the comments in dynamic_annotations.h */ -int RunningOnValgrind(void) { - static volatile int running_on_valgrind = -1; - /* C doesn't have thread-safe initialization of statics, and we - don't want to depend on pthread_once here, so hack it. */ - int local_running_on_valgrind = running_on_valgrind; - if (local_running_on_valgrind == -1) - running_on_valgrind = local_running_on_valgrind = GetRunningOnValgrind(); - return local_running_on_valgrind; -} - -#endif /* DYNAMIC_ANNOTATIONS_ENABLED == 1 */ diff --git a/contrib/tools/python3/src/Python/dynload_shlib.c b/contrib/tools/python3/src/Python/dynload_shlib.c deleted file mode 100644 index 23828898d35..00000000000 --- a/contrib/tools/python3/src/Python/dynload_shlib.c +++ /dev/null @@ -1,133 +0,0 @@ - -/* Support for dynamic loading of extension modules */ - -#include "Python.h" -#include "pycore_interp.h" // _PyInterpreterState.dlopenflags -#include "pycore_pystate.h" // _PyInterpreterState_GET() -#include "importdl.h" - -#include <sys/types.h> -#include <sys/stat.h> - -#if defined(__NetBSD__) -#include <sys/param.h> -#if (NetBSD < 199712) -#include <nlist.h> -#include <link.h> -#define dlerror() "error in dynamic linking" -#endif -#endif /* NetBSD */ - -#ifdef HAVE_DLFCN_H -#include <dlfcn.h> -#endif - -#if (defined(__OpenBSD__) || defined(__NetBSD__)) && !defined(__ELF__) -#define LEAD_UNDERSCORE "_" -#else -#define LEAD_UNDERSCORE "" -#endif - -/* The .so extension module ABI tag, supplied by the Makefile via - Makefile.pre.in and configure. This is used to discriminate between - incompatible .so files so that extensions for different Python builds can - live in the same directory. E.g. foomodule.cpython-32.so -*/ - -const char *_PyImport_DynLoadFiletab[] = { -#ifdef __CYGWIN__ - ".dll", -#else /* !__CYGWIN__ */ - "." SOABI ".so", -#ifdef ALT_SOABI - "." ALT_SOABI ".so", -#endif - ".abi" PYTHON_ABI_STRING ".so", - ".so", -#endif /* __CYGWIN__ */ - NULL, -}; - -static struct { - dev_t dev; - ino_t ino; - void *handle; -} handles[128]; -static int nhandles = 0; - - -dl_funcptr -_PyImport_FindSharedFuncptr(const char *prefix, - const char *shortname, - const char *pathname, FILE *fp) -{ - dl_funcptr p; - void *handle; - char funcname[258]; - char pathbuf[260]; - int dlopenflags=0; - - if (strchr(pathname, '/') == NULL) { - /* Prefix bare filename with "./" */ - PyOS_snprintf(pathbuf, sizeof(pathbuf), "./%-.255s", pathname); - pathname = pathbuf; - } - - PyOS_snprintf(funcname, sizeof(funcname), - LEAD_UNDERSCORE "%.20s_%.200s", prefix, shortname); - - if (fp != NULL) { - int i; - struct _Py_stat_struct status; - if (_Py_fstat(fileno(fp), &status) == -1) - return NULL; - for (i = 0; i < nhandles; i++) { - if (status.st_dev == handles[i].dev && - status.st_ino == handles[i].ino) { - p = (dl_funcptr) dlsym(handles[i].handle, - funcname); - return p; - } - } - if (nhandles < 128) { - handles[nhandles].dev = status.st_dev; - handles[nhandles].ino = status.st_ino; - } - } - - dlopenflags = _PyInterpreterState_GET()->dlopenflags; - - handle = dlopen(pathname, dlopenflags); - - if (handle == NULL) { - PyObject *mod_name; - PyObject *path; - PyObject *error_ob; - const char *error = dlerror(); - if (error == NULL) - error = "unknown dlopen() error"; - error_ob = PyUnicode_DecodeLocale(error, "surrogateescape"); - if (error_ob == NULL) - return NULL; - mod_name = PyUnicode_FromString(shortname); - if (mod_name == NULL) { - Py_DECREF(error_ob); - return NULL; - } - path = PyUnicode_DecodeFSDefault(pathname); - if (path == NULL) { - Py_DECREF(error_ob); - Py_DECREF(mod_name); - return NULL; - } - PyErr_SetImportError(error_ob, mod_name, path); - Py_DECREF(error_ob); - Py_DECREF(mod_name); - Py_DECREF(path); - return NULL; - } - if (fp != NULL && nhandles < 128) - handles[nhandles++].handle = handle; - p = (dl_funcptr) dlsym(handle, funcname); - return p; -} diff --git a/contrib/tools/python3/src/Python/dynload_win.c b/contrib/tools/python3/src/Python/dynload_win.c deleted file mode 100644 index 5702ab2cd71..00000000000 --- a/contrib/tools/python3/src/Python/dynload_win.c +++ /dev/null @@ -1,288 +0,0 @@ - -/* Support for dynamic loading of extension modules */ - -#include "Python.h" - -#ifdef HAVE_DIRECT_H -#include <direct.h> -#endif -#include <ctype.h> - -#include "importdl.h" -#include "patchlevel.h" -#include <windows.h> - -#ifdef _DEBUG -#define PYD_DEBUG_SUFFIX "_d" -#else -#define PYD_DEBUG_SUFFIX "" -#endif - -#ifdef PYD_PLATFORM_TAG -#define PYD_TAGGED_SUFFIX PYD_DEBUG_SUFFIX ".cp" Py_STRINGIFY(PY_MAJOR_VERSION) Py_STRINGIFY(PY_MINOR_VERSION) "-" PYD_PLATFORM_TAG ".pyd" -#else -#define PYD_TAGGED_SUFFIX PYD_DEBUG_SUFFIX ".cp" Py_STRINGIFY(PY_MAJOR_VERSION) Py_STRINGIFY(PY_MINOR_VERSION) ".pyd" -#endif - -#define PYD_UNTAGGED_SUFFIX PYD_DEBUG_SUFFIX ".pyd" - -const char *_PyImport_DynLoadFiletab[] = { - PYD_TAGGED_SUFFIX, - PYD_UNTAGGED_SUFFIX, - NULL -}; - -/* Function to return the name of the "python" DLL that the supplied module - directly imports. Looks through the list of imported modules and - returns the first entry that starts with "python" (case sensitive) and - is followed by nothing but numbers until the separator (period). - - Returns a pointer to the import name, or NULL if no matching name was - located. - - This function parses through the PE header for the module as loaded in - memory by the system loader. The PE header is accessed as documented by - Microsoft in the MSDN PE and COFF specification (2/99), and handles - both PE32 and PE32+. It only worries about the direct import table and - not the delay load import table since it's unlikely an extension is - going to be delay loading Python (after all, it's already loaded). - - If any magic values are not found (e.g., the PE header or optional - header magic), then this function simply returns NULL. */ - -#define DWORD_AT(mem) (*(DWORD *)(mem)) -#define WORD_AT(mem) (*(WORD *)(mem)) - -static char *GetPythonImport (HINSTANCE hModule) -{ - unsigned char *dllbase, *import_data, *import_name; - DWORD pe_offset, opt_offset; - WORD opt_magic; - int num_dict_off, import_off; - - /* Safety check input */ - if (hModule == NULL) { - return NULL; - } - - /* Module instance is also the base load address. First portion of - memory is the MS-DOS loader, which holds the offset to the PE - header (from the load base) at 0x3C */ - dllbase = (unsigned char *)hModule; - pe_offset = DWORD_AT(dllbase + 0x3C); - - /* The PE signature must be "PE\0\0" */ - if (memcmp(dllbase+pe_offset,"PE\0\0",4)) { - return NULL; - } - - /* Following the PE signature is the standard COFF header (20 - bytes) and then the optional header. The optional header starts - with a magic value of 0x10B for PE32 or 0x20B for PE32+ (PE32+ - uses 64-bits for some fields). It might also be 0x107 for a ROM - image, but we don't process that here. - - The optional header ends with a data dictionary that directly - points to certain types of data, among them the import entries - (in the second table entry). Based on the header type, we - determine offsets for the data dictionary count and the entry - within the dictionary pointing to the imports. */ - - opt_offset = pe_offset + 4 + 20; - opt_magic = WORD_AT(dllbase+opt_offset); - if (opt_magic == 0x10B) { - /* PE32 */ - num_dict_off = 92; - import_off = 104; - } else if (opt_magic == 0x20B) { - /* PE32+ */ - num_dict_off = 108; - import_off = 120; - } else { - /* Unsupported */ - return NULL; - } - - /* Now if an import table exists, offset to it and walk the list of - imports. The import table is an array (ending when an entry has - empty values) of structures (20 bytes each), which contains (at - offset 12) a relative address (to the module base) at which a - string constant holding the import name is located. */ - - if (DWORD_AT(dllbase + opt_offset + num_dict_off) >= 2) { - /* We have at least 2 tables - the import table is the second - one. But still it may be that the table size is zero */ - if (0 == DWORD_AT(dllbase + opt_offset + import_off + sizeof(DWORD))) - return NULL; - import_data = dllbase + DWORD_AT(dllbase + - opt_offset + - import_off); - while (DWORD_AT(import_data)) { - import_name = dllbase + DWORD_AT(import_data+12); - if (strlen(import_name) >= 6 && - !strncmp(import_name,"python",6)) { - char *pch; - -#ifndef _DEBUG - /* In a release version, don't claim that python3.dll is - a Python DLL. */ - if (strcmp(import_name, "python3.dll") == 0) { - import_data += 20; - continue; - } -#endif - - /* Ensure python prefix is followed only - by numbers to the end of the basename */ - pch = import_name + 6; -#ifdef _DEBUG - while (*pch && pch[0] != '_' && pch[1] != 'd' && pch[2] != '.') { -#else - while (*pch && *pch != '.') { -#endif - if (*pch >= '0' && *pch <= '9') { - pch++; - } else { - pch = NULL; - break; - } - } - - if (pch) { - /* Found it - return the name */ - return import_name; - } - } - import_data += 20; - } - } - - return NULL; -} - -dl_funcptr _PyImport_FindSharedFuncptrWindows(const char *prefix, - const char *shortname, - PyObject *pathname, FILE *fp) -{ - dl_funcptr p; - char funcname[258], *import_python; - - _Py_CheckPython3(); - -#if USE_UNICODE_WCHAR_CACHE - const wchar_t *wpathname = _PyUnicode_AsUnicode(pathname); -#else /* USE_UNICODE_WCHAR_CACHE */ - wchar_t *wpathname = PyUnicode_AsWideCharString(pathname, NULL); -#endif /* USE_UNICODE_WCHAR_CACHE */ - if (wpathname == NULL) - return NULL; - - PyOS_snprintf(funcname, sizeof(funcname), "%.20s_%.200s", prefix, shortname); - - { - HINSTANCE hDLL = NULL; - unsigned int old_mode; - - /* Don't display a message box when Python can't load a DLL */ - old_mode = SetErrorMode(SEM_FAILCRITICALERRORS); - - /* bpo-36085: We use LoadLibraryEx with restricted search paths - to avoid DLL preloading attacks and enable use of the - AddDllDirectory function. We add SEARCH_DLL_LOAD_DIR to - ensure DLLs adjacent to the PYD are preferred. */ - Py_BEGIN_ALLOW_THREADS - hDLL = LoadLibraryExW(wpathname, NULL, - LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | - LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR); - Py_END_ALLOW_THREADS -#if !USE_UNICODE_WCHAR_CACHE - PyMem_Free(wpathname); -#endif /* USE_UNICODE_WCHAR_CACHE */ - - /* restore old error mode settings */ - SetErrorMode(old_mode); - - if (hDLL==NULL){ - PyObject *message; - unsigned int errorCode; - - /* Get an error string from Win32 error code */ - wchar_t theInfo[256]; /* Pointer to error text - from system */ - int theLength; /* Length of error text */ - - errorCode = GetLastError(); - - theLength = FormatMessageW( - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, /* flags */ - NULL, /* message source */ - errorCode, /* the message (error) ID */ - MAKELANGID(LANG_NEUTRAL, - SUBLANG_DEFAULT), - /* Default language */ - theInfo, /* the buffer */ - sizeof(theInfo) / sizeof(wchar_t), /* size in wchars */ - NULL); /* no additional format args. */ - - /* Problem: could not get the error message. - This should not happen if called correctly. */ - if (theLength == 0) { - message = PyUnicode_FromFormat( - "DLL load failed with error code %u while importing %s", - errorCode, shortname); - } else { - /* For some reason a \r\n - is appended to the text */ - if (theLength >= 2 && - theInfo[theLength-2] == '\r' && - theInfo[theLength-1] == '\n') { - theLength -= 2; - theInfo[theLength] = '\0'; - } - message = PyUnicode_FromFormat( - "DLL load failed while importing %s: ", shortname); - - PyUnicode_AppendAndDel(&message, - PyUnicode_FromWideChar( - theInfo, - theLength)); - } - if (message != NULL) { - PyObject *shortname_obj = PyUnicode_FromString(shortname); - PyErr_SetImportError(message, shortname_obj, pathname); - Py_XDECREF(shortname_obj); - Py_DECREF(message); - } - return NULL; - } else { - char buffer[256]; - - PyOS_snprintf(buffer, sizeof(buffer), -#ifdef _DEBUG - "python%d%d_d.dll", -#else - "python%d%d.dll", -#endif - PY_MAJOR_VERSION,PY_MINOR_VERSION); - import_python = GetPythonImport(hDLL); - - if (import_python && - _stricmp(buffer,import_python)) { - PyErr_Format(PyExc_ImportError, - "Module use of %.150s conflicts " - "with this version of Python.", - import_python); - Py_BEGIN_ALLOW_THREADS - FreeLibrary(hDLL); - Py_END_ALLOW_THREADS - return NULL; - } - } - Py_BEGIN_ALLOW_THREADS - p = GetProcAddress(hDLL, funcname); - Py_END_ALLOW_THREADS - } - - return p; -} diff --git a/contrib/tools/python3/src/Python/errors.c b/contrib/tools/python3/src/Python/errors.c deleted file mode 100644 index bc1b55e440e..00000000000 --- a/contrib/tools/python3/src/Python/errors.c +++ /dev/null @@ -1,1808 +0,0 @@ - -/* Error handling */ - -#include "Python.h" -#include "pycore_initconfig.h" -#include "pycore_object.h" // _PyType_GetQualName -#include "pycore_pyerrors.h" -#include "pycore_pystate.h" // _PyThreadState_GET() -#include "pycore_sysmodule.h" -#include "pycore_traceback.h" - -#ifndef __STDC__ -#ifndef MS_WINDOWS -extern char *strerror(int); -#endif -#endif - -#ifdef MS_WINDOWS -#include <windows.h> -#include <winbase.h> -#endif - -#include <ctype.h> - -#ifdef __cplusplus -extern "C" { -#endif - -_Py_IDENTIFIER(__module__); -_Py_IDENTIFIER(builtins); -_Py_IDENTIFIER(stderr); -_Py_IDENTIFIER(flush); - -/* Forward declarations */ -static PyObject * -_PyErr_FormatV(PyThreadState *tstate, PyObject *exception, - const char *format, va_list vargs); - - -void -_PyErr_Restore(PyThreadState *tstate, PyObject *type, PyObject *value, - PyObject *traceback) -{ - PyObject *oldtype, *oldvalue, *oldtraceback; - - if (traceback != NULL && !PyTraceBack_Check(traceback)) { - /* XXX Should never happen -- fatal error instead? */ - /* Well, it could be None. */ - Py_DECREF(traceback); - traceback = NULL; - } - - /* Save these in locals to safeguard against recursive - invocation through Py_XDECREF */ - oldtype = tstate->curexc_type; - oldvalue = tstate->curexc_value; - oldtraceback = tstate->curexc_traceback; - - tstate->curexc_type = type; - tstate->curexc_value = value; - tstate->curexc_traceback = traceback; - - Py_XDECREF(oldtype); - Py_XDECREF(oldvalue); - Py_XDECREF(oldtraceback); -} - -void -PyErr_Restore(PyObject *type, PyObject *value, PyObject *traceback) -{ - PyThreadState *tstate = _PyThreadState_GET(); - _PyErr_Restore(tstate, type, value, traceback); -} - - -_PyErr_StackItem * -_PyErr_GetTopmostException(PyThreadState *tstate) -{ - _PyErr_StackItem *exc_info = tstate->exc_info; - while ((exc_info->exc_type == NULL || exc_info->exc_type == Py_None) && - exc_info->previous_item != NULL) - { - exc_info = exc_info->previous_item; - } - return exc_info; -} - -static PyObject* -_PyErr_CreateException(PyObject *exception_type, PyObject *value) -{ - PyObject *exc; - - if (value == NULL || value == Py_None) { - exc = _PyObject_CallNoArg(exception_type); - } - else if (PyTuple_Check(value)) { - exc = PyObject_Call(exception_type, value, NULL); - } - else { - exc = PyObject_CallOneArg(exception_type, value); - } - - if (exc != NULL && !PyExceptionInstance_Check(exc)) { - PyErr_Format(PyExc_TypeError, - "calling %R should have returned an instance of " - "BaseException, not %s", - exception_type, Py_TYPE(exc)->tp_name); - Py_CLEAR(exc); - } - - return exc; -} - -void -_PyErr_SetObject(PyThreadState *tstate, PyObject *exception, PyObject *value) -{ - PyObject *exc_value; - PyObject *tb = NULL; - - if (exception != NULL && - !PyExceptionClass_Check(exception)) { - _PyErr_Format(tstate, PyExc_SystemError, - "_PyErr_SetObject: " - "exception %R is not a BaseException subclass", - exception); - return; - } - - Py_XINCREF(value); - exc_value = _PyErr_GetTopmostException(tstate)->exc_value; - if (exc_value != NULL && exc_value != Py_None) { - /* Implicit exception chaining */ - Py_INCREF(exc_value); - if (value == NULL || !PyExceptionInstance_Check(value)) { - /* We must normalize the value right now */ - PyObject *fixed_value; - - /* Issue #23571: functions must not be called with an - exception set */ - _PyErr_Clear(tstate); - - fixed_value = _PyErr_CreateException(exception, value); - Py_XDECREF(value); - if (fixed_value == NULL) { - Py_DECREF(exc_value); - return; - } - - value = fixed_value; - } - - /* Avoid creating new reference cycles through the - context chain, while taking care not to hang on - pre-existing ones. - This is O(chain length) but context chains are - usually very short. Sensitive readers may try - to inline the call to PyException_GetContext. */ - if (exc_value != value) { - PyObject *o = exc_value, *context; - PyObject *slow_o = o; /* Floyd's cycle detection algo */ - int slow_update_toggle = 0; - while ((context = PyException_GetContext(o))) { - Py_DECREF(context); - if (context == value) { - PyException_SetContext(o, NULL); - break; - } - o = context; - if (o == slow_o) { - /* pre-existing cycle - all exceptions on the - path were visited and checked. */ - break; - } - if (slow_update_toggle) { - slow_o = PyException_GetContext(slow_o); - Py_DECREF(slow_o); - } - slow_update_toggle = !slow_update_toggle; - } - PyException_SetContext(value, exc_value); - } - else { - Py_DECREF(exc_value); - } - } - if (value != NULL && PyExceptionInstance_Check(value)) - tb = PyException_GetTraceback(value); - Py_XINCREF(exception); - _PyErr_Restore(tstate, exception, value, tb); -} - -void -PyErr_SetObject(PyObject *exception, PyObject *value) -{ - PyThreadState *tstate = _PyThreadState_GET(); - _PyErr_SetObject(tstate, exception, value); -} - -/* Set a key error with the specified argument, wrapping it in a - * tuple automatically so that tuple keys are not unpacked as the - * exception arguments. */ -void -_PyErr_SetKeyError(PyObject *arg) -{ - PyThreadState *tstate = _PyThreadState_GET(); - PyObject *tup = PyTuple_Pack(1, arg); - if (!tup) { - /* caller will expect error to be set anyway */ - return; - } - _PyErr_SetObject(tstate, PyExc_KeyError, tup); - Py_DECREF(tup); -} - -void -_PyErr_SetNone(PyThreadState *tstate, PyObject *exception) -{ - _PyErr_SetObject(tstate, exception, (PyObject *)NULL); -} - - -void -PyErr_SetNone(PyObject *exception) -{ - PyThreadState *tstate = _PyThreadState_GET(); - _PyErr_SetNone(tstate, exception); -} - - -void -_PyErr_SetString(PyThreadState *tstate, PyObject *exception, - const char *string) -{ - PyObject *value = PyUnicode_FromString(string); - _PyErr_SetObject(tstate, exception, value); - Py_XDECREF(value); -} - -void -PyErr_SetString(PyObject *exception, const char *string) -{ - PyThreadState *tstate = _PyThreadState_GET(); - _PyErr_SetString(tstate, exception, string); -} - - -PyObject* _Py_HOT_FUNCTION -PyErr_Occurred(void) -{ - /* The caller must hold the GIL. */ - assert(PyGILState_Check()); - - PyThreadState *tstate = _PyThreadState_GET(); - return _PyErr_Occurred(tstate); -} - - -int -PyErr_GivenExceptionMatches(PyObject *err, PyObject *exc) -{ - if (err == NULL || exc == NULL) { - /* maybe caused by "import exceptions" that failed early on */ - return 0; - } - if (PyTuple_Check(exc)) { - Py_ssize_t i, n; - n = PyTuple_Size(exc); - for (i = 0; i < n; i++) { - /* Test recursively */ - if (PyErr_GivenExceptionMatches( - err, PyTuple_GET_ITEM(exc, i))) - { - return 1; - } - } - return 0; - } - /* err might be an instance, so check its class. */ - if (PyExceptionInstance_Check(err)) - err = PyExceptionInstance_Class(err); - - if (PyExceptionClass_Check(err) && PyExceptionClass_Check(exc)) { - return PyType_IsSubtype((PyTypeObject *)err, (PyTypeObject *)exc); - } - - return err == exc; -} - - -int -_PyErr_ExceptionMatches(PyThreadState *tstate, PyObject *exc) -{ - return PyErr_GivenExceptionMatches(_PyErr_Occurred(tstate), exc); -} - - -int -PyErr_ExceptionMatches(PyObject *exc) -{ - PyThreadState *tstate = _PyThreadState_GET(); - return _PyErr_ExceptionMatches(tstate, exc); -} - - -#ifndef Py_NORMALIZE_RECURSION_LIMIT -#define Py_NORMALIZE_RECURSION_LIMIT 32 -#endif - -/* Used in many places to normalize a raised exception, including in - eval_code2(), do_raise(), and PyErr_Print() - - XXX: should PyErr_NormalizeException() also call - PyException_SetTraceback() with the resulting value and tb? -*/ -void -_PyErr_NormalizeException(PyThreadState *tstate, PyObject **exc, - PyObject **val, PyObject **tb) -{ - int recursion_depth = 0; - tstate->recursion_headroom++; - PyObject *type, *value, *initial_tb; - - restart: - type = *exc; - if (type == NULL) { - /* There was no exception, so nothing to do. */ - tstate->recursion_headroom--; - return; - } - - value = *val; - /* If PyErr_SetNone() was used, the value will have been actually - set to NULL. - */ - if (!value) { - value = Py_None; - Py_INCREF(value); - } - - /* Normalize the exception so that if the type is a class, the - value will be an instance. - */ - if (PyExceptionClass_Check(type)) { - PyObject *inclass = NULL; - int is_subclass = 0; - - if (PyExceptionInstance_Check(value)) { - inclass = PyExceptionInstance_Class(value); - is_subclass = PyObject_IsSubclass(inclass, type); - if (is_subclass < 0) { - goto error; - } - } - - /* If the value was not an instance, or is not an instance - whose class is (or is derived from) type, then use the - value as an argument to instantiation of the type - class. - */ - if (!is_subclass) { - PyObject *fixed_value = _PyErr_CreateException(type, value); - if (fixed_value == NULL) { - goto error; - } - Py_DECREF(value); - value = fixed_value; - } - /* If the class of the instance doesn't exactly match the - class of the type, believe the instance. - */ - else if (inclass != type) { - Py_INCREF(inclass); - Py_DECREF(type); - type = inclass; - } - } - *exc = type; - *val = value; - tstate->recursion_headroom--; - return; - - error: - Py_DECREF(type); - Py_DECREF(value); - recursion_depth++; - if (recursion_depth == Py_NORMALIZE_RECURSION_LIMIT) { - _PyErr_SetString(tstate, PyExc_RecursionError, - "maximum recursion depth exceeded " - "while normalizing an exception"); - } - /* If the new exception doesn't set a traceback and the old - exception had a traceback, use the old traceback for the - new exception. It's better than nothing. - */ - initial_tb = *tb; - _PyErr_Fetch(tstate, exc, val, tb); - assert(*exc != NULL); - if (initial_tb != NULL) { - if (*tb == NULL) - *tb = initial_tb; - else - Py_DECREF(initial_tb); - } - /* Abort when Py_NORMALIZE_RECURSION_LIMIT has been exceeded, and the - corresponding RecursionError could not be normalized, and the - MemoryError raised when normalize this RecursionError could not be - normalized. */ - if (recursion_depth >= Py_NORMALIZE_RECURSION_LIMIT + 2) { - if (PyErr_GivenExceptionMatches(*exc, PyExc_MemoryError)) { - Py_FatalError("Cannot recover from MemoryErrors " - "while normalizing exceptions."); - } - else { - Py_FatalError("Cannot recover from the recursive normalization " - "of an exception."); - } - } - goto restart; -} - - -void -PyErr_NormalizeException(PyObject **exc, PyObject **val, PyObject **tb) -{ - PyThreadState *tstate = _PyThreadState_GET(); - _PyErr_NormalizeException(tstate, exc, val, tb); -} - - -void -_PyErr_Fetch(PyThreadState *tstate, PyObject **p_type, PyObject **p_value, - PyObject **p_traceback) -{ - *p_type = tstate->curexc_type; - *p_value = tstate->curexc_value; - *p_traceback = tstate->curexc_traceback; - - tstate->curexc_type = NULL; - tstate->curexc_value = NULL; - tstate->curexc_traceback = NULL; -} - - -void -PyErr_Fetch(PyObject **p_type, PyObject **p_value, PyObject **p_traceback) -{ - PyThreadState *tstate = _PyThreadState_GET(); - _PyErr_Fetch(tstate, p_type, p_value, p_traceback); -} - - -void -_PyErr_Clear(PyThreadState *tstate) -{ - _PyErr_Restore(tstate, NULL, NULL, NULL); -} - - -void -PyErr_Clear(void) -{ - PyThreadState *tstate = _PyThreadState_GET(); - _PyErr_Clear(tstate); -} - - -void -_PyErr_GetExcInfo(PyThreadState *tstate, - PyObject **p_type, PyObject **p_value, PyObject **p_traceback) -{ - _PyErr_StackItem *exc_info = _PyErr_GetTopmostException(tstate); - *p_type = exc_info->exc_type; - *p_value = exc_info->exc_value; - *p_traceback = exc_info->exc_traceback; - - Py_XINCREF(*p_type); - Py_XINCREF(*p_value); - Py_XINCREF(*p_traceback); -} - - -void -PyErr_GetExcInfo(PyObject **p_type, PyObject **p_value, PyObject **p_traceback) -{ - PyThreadState *tstate = _PyThreadState_GET(); - _PyErr_GetExcInfo(tstate, p_type, p_value, p_traceback); -} - -void -PyErr_SetExcInfo(PyObject *p_type, PyObject *p_value, PyObject *p_traceback) -{ - PyObject *oldtype, *oldvalue, *oldtraceback; - PyThreadState *tstate = _PyThreadState_GET(); - - oldtype = tstate->exc_info->exc_type; - oldvalue = tstate->exc_info->exc_value; - oldtraceback = tstate->exc_info->exc_traceback; - - tstate->exc_info->exc_type = p_type; - tstate->exc_info->exc_value = p_value; - tstate->exc_info->exc_traceback = p_traceback; - - Py_XDECREF(oldtype); - Py_XDECREF(oldvalue); - Py_XDECREF(oldtraceback); -} - -/* Like PyErr_Restore(), but if an exception is already set, - set the context associated with it. - - The caller is responsible for ensuring that this call won't create - any cycles in the exception context chain. */ -void -_PyErr_ChainExceptions(PyObject *exc, PyObject *val, PyObject *tb) -{ - if (exc == NULL) - return; - - PyThreadState *tstate = _PyThreadState_GET(); - - if (!PyExceptionClass_Check(exc)) { - _PyErr_Format(tstate, PyExc_SystemError, - "_PyErr_ChainExceptions: " - "exception %R is not a BaseException subclass", - exc); - return; - } - - if (_PyErr_Occurred(tstate)) { - PyObject *exc2, *val2, *tb2; - _PyErr_Fetch(tstate, &exc2, &val2, &tb2); - _PyErr_NormalizeException(tstate, &exc, &val, &tb); - if (tb != NULL) { - PyException_SetTraceback(val, tb); - Py_DECREF(tb); - } - Py_DECREF(exc); - _PyErr_NormalizeException(tstate, &exc2, &val2, &tb2); - PyException_SetContext(val2, val); - _PyErr_Restore(tstate, exc2, val2, tb2); - } - else { - _PyErr_Restore(tstate, exc, val, tb); - } -} - -/* Set the currently set exception's context to the given exception. - - If the provided exc_info is NULL, then the current Python thread state's - exc_info will be used for the context instead. - - This function can only be called when _PyErr_Occurred() is true. - Also, this function won't create any cycles in the exception context - chain to the extent that _PyErr_SetObject ensures this. */ -void -_PyErr_ChainStackItem(_PyErr_StackItem *exc_info) -{ - PyThreadState *tstate = _PyThreadState_GET(); - assert(_PyErr_Occurred(tstate)); - - int exc_info_given; - if (exc_info == NULL) { - exc_info_given = 0; - exc_info = tstate->exc_info; - } else { - exc_info_given = 1; - } - if (exc_info->exc_type == NULL || exc_info->exc_type == Py_None) { - return; - } - - _PyErr_StackItem *saved_exc_info; - if (exc_info_given) { - /* Temporarily set the thread state's exc_info since this is what - _PyErr_SetObject uses for implicit exception chaining. */ - saved_exc_info = tstate->exc_info; - tstate->exc_info = exc_info; - } - - PyObject *exc, *val, *tb; - _PyErr_Fetch(tstate, &exc, &val, &tb); - - PyObject *exc2, *val2, *tb2; - exc2 = exc_info->exc_type; - val2 = exc_info->exc_value; - tb2 = exc_info->exc_traceback; - _PyErr_NormalizeException(tstate, &exc2, &val2, &tb2); - if (tb2 != NULL) { - PyException_SetTraceback(val2, tb2); - } - - /* _PyErr_SetObject sets the context from PyThreadState. */ - _PyErr_SetObject(tstate, exc, val); - Py_DECREF(exc); // since _PyErr_Occurred was true - Py_XDECREF(val); - Py_XDECREF(tb); - - if (exc_info_given) { - tstate->exc_info = saved_exc_info; - } -} - -static PyObject * -_PyErr_FormatVFromCause(PyThreadState *tstate, PyObject *exception, - const char *format, va_list vargs) -{ - PyObject *exc, *val, *val2, *tb; - - assert(_PyErr_Occurred(tstate)); - _PyErr_Fetch(tstate, &exc, &val, &tb); - _PyErr_NormalizeException(tstate, &exc, &val, &tb); - if (tb != NULL) { - PyException_SetTraceback(val, tb); - Py_DECREF(tb); - } - Py_DECREF(exc); - assert(!_PyErr_Occurred(tstate)); - - _PyErr_FormatV(tstate, exception, format, vargs); - - _PyErr_Fetch(tstate, &exc, &val2, &tb); - _PyErr_NormalizeException(tstate, &exc, &val2, &tb); - Py_INCREF(val); - PyException_SetCause(val2, val); - PyException_SetContext(val2, val); - _PyErr_Restore(tstate, exc, val2, tb); - - return NULL; -} - -PyObject * -_PyErr_FormatFromCauseTstate(PyThreadState *tstate, PyObject *exception, - const char *format, ...) -{ - va_list vargs; -#ifdef HAVE_STDARG_PROTOTYPES - va_start(vargs, format); -#else - va_start(vargs); -#endif - _PyErr_FormatVFromCause(tstate, exception, format, vargs); - va_end(vargs); - return NULL; -} - -PyObject * -_PyErr_FormatFromCause(PyObject *exception, const char *format, ...) -{ - PyThreadState *tstate = _PyThreadState_GET(); - va_list vargs; -#ifdef HAVE_STDARG_PROTOTYPES - va_start(vargs, format); -#else - va_start(vargs); -#endif - _PyErr_FormatVFromCause(tstate, exception, format, vargs); - va_end(vargs); - return NULL; -} - -/* Convenience functions to set a type error exception and return 0 */ - -int -PyErr_BadArgument(void) -{ - PyThreadState *tstate = _PyThreadState_GET(); - _PyErr_SetString(tstate, PyExc_TypeError, - "bad argument type for built-in operation"); - return 0; -} - -PyObject * -_PyErr_NoMemory(PyThreadState *tstate) -{ - if (Py_IS_TYPE(PyExc_MemoryError, NULL)) { - /* PyErr_NoMemory() has been called before PyExc_MemoryError has been - initialized by _PyExc_Init() */ - Py_FatalError("Out of memory and PyExc_MemoryError is not " - "initialized yet"); - } - _PyErr_SetNone(tstate, PyExc_MemoryError); - return NULL; -} - -PyObject * -PyErr_NoMemory(void) -{ - PyThreadState *tstate = _PyThreadState_GET(); - return _PyErr_NoMemory(tstate); -} - -PyObject * -PyErr_SetFromErrnoWithFilenameObject(PyObject *exc, PyObject *filenameObject) -{ - return PyErr_SetFromErrnoWithFilenameObjects(exc, filenameObject, NULL); -} - -PyObject * -PyErr_SetFromErrnoWithFilenameObjects(PyObject *exc, PyObject *filenameObject, PyObject *filenameObject2) -{ - PyThreadState *tstate = _PyThreadState_GET(); - PyObject *message; - PyObject *v, *args; - int i = errno; -#ifdef MS_WINDOWS - WCHAR *s_buf = NULL; -#endif /* Unix/Windows */ - -#ifdef EINTR - if (i == EINTR && PyErr_CheckSignals()) - return NULL; -#endif - -#ifndef MS_WINDOWS - if (i != 0) { - const char *s = strerror(i); - message = PyUnicode_DecodeLocale(s, "surrogateescape"); - } - else { - /* Sometimes errno didn't get set */ - message = PyUnicode_FromString("Error"); - } -#else - if (i == 0) - message = PyUnicode_FromString("Error"); /* Sometimes errno didn't get set */ - else - { - /* Note that the Win32 errors do not lineup with the - errno error. So if the error is in the MSVC error - table, we use it, otherwise we assume it really _is_ - a Win32 error code - */ - if (i > 0 && i < _sys_nerr) { - message = PyUnicode_FromString(_sys_errlist[i]); - } - else { - int len = FormatMessageW( - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, /* no message source */ - i, - MAKELANGID(LANG_NEUTRAL, - SUBLANG_DEFAULT), - /* Default language */ - (LPWSTR) &s_buf, - 0, /* size not used */ - NULL); /* no args */ - if (len==0) { - /* Only ever seen this in out-of-mem - situations */ - s_buf = NULL; - message = PyUnicode_FromFormat("Windows Error 0x%x", i); - } else { - /* remove trailing cr/lf and dots */ - while (len > 0 && (s_buf[len-1] <= L' ' || s_buf[len-1] == L'.')) - s_buf[--len] = L'\0'; - message = PyUnicode_FromWideChar(s_buf, len); - } - } - } -#endif /* Unix/Windows */ - - if (message == NULL) - { -#ifdef MS_WINDOWS - LocalFree(s_buf); -#endif - return NULL; - } - - if (filenameObject != NULL) { - if (filenameObject2 != NULL) - args = Py_BuildValue("(iOOiO)", i, message, filenameObject, 0, filenameObject2); - else - args = Py_BuildValue("(iOO)", i, message, filenameObject); - } else { - assert(filenameObject2 == NULL); - args = Py_BuildValue("(iO)", i, message); - } - Py_DECREF(message); - - if (args != NULL) { - v = PyObject_Call(exc, args, NULL); - Py_DECREF(args); - if (v != NULL) { - _PyErr_SetObject(tstate, (PyObject *) Py_TYPE(v), v); - Py_DECREF(v); - } - } -#ifdef MS_WINDOWS - LocalFree(s_buf); -#endif - return NULL; -} - -PyObject * -PyErr_SetFromErrnoWithFilename(PyObject *exc, const char *filename) -{ - PyObject *name = filename ? PyUnicode_DecodeFSDefault(filename) : NULL; - PyObject *result = PyErr_SetFromErrnoWithFilenameObjects(exc, name, NULL); - Py_XDECREF(name); - return result; -} - -#ifdef MS_WINDOWS -PyObject * -PyErr_SetFromErrnoWithUnicodeFilename(PyObject *exc, const Py_UNICODE *filename) -{ - PyObject *name = filename ? PyUnicode_FromWideChar(filename, -1) : NULL; - PyObject *result = PyErr_SetFromErrnoWithFilenameObjects(exc, name, NULL); - Py_XDECREF(name); - return result; -} -#endif /* MS_WINDOWS */ - -PyObject * -PyErr_SetFromErrno(PyObject *exc) -{ - return PyErr_SetFromErrnoWithFilenameObjects(exc, NULL, NULL); -} - -#ifdef MS_WINDOWS -/* Windows specific error code handling */ -PyObject *PyErr_SetExcFromWindowsErrWithFilenameObject( - PyObject *exc, - int ierr, - PyObject *filenameObject) -{ - return PyErr_SetExcFromWindowsErrWithFilenameObjects(exc, ierr, - filenameObject, NULL); -} - -PyObject *PyErr_SetExcFromWindowsErrWithFilenameObjects( - PyObject *exc, - int ierr, - PyObject *filenameObject, - PyObject *filenameObject2) -{ - PyThreadState *tstate = _PyThreadState_GET(); - int len; - WCHAR *s_buf = NULL; /* Free via LocalFree */ - PyObject *message; - PyObject *args, *v; - - DWORD err = (DWORD)ierr; - if (err==0) { - err = GetLastError(); - } - - len = FormatMessageW( - /* Error API error */ - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, /* no message source */ - err, - MAKELANGID(LANG_NEUTRAL, - SUBLANG_DEFAULT), /* Default language */ - (LPWSTR) &s_buf, - 0, /* size not used */ - NULL); /* no args */ - if (len==0) { - /* Only seen this in out of mem situations */ - message = PyUnicode_FromFormat("Windows Error 0x%x", err); - s_buf = NULL; - } else { - /* remove trailing cr/lf and dots */ - while (len > 0 && (s_buf[len-1] <= L' ' || s_buf[len-1] == L'.')) - s_buf[--len] = L'\0'; - message = PyUnicode_FromWideChar(s_buf, len); - } - - if (message == NULL) - { - LocalFree(s_buf); - return NULL; - } - - if (filenameObject == NULL) { - assert(filenameObject2 == NULL); - filenameObject = filenameObject2 = Py_None; - } - else if (filenameObject2 == NULL) - filenameObject2 = Py_None; - /* This is the constructor signature for OSError. - The POSIX translation will be figured out by the constructor. */ - args = Py_BuildValue("(iOOiO)", 0, message, filenameObject, err, filenameObject2); - Py_DECREF(message); - - if (args != NULL) { - v = PyObject_Call(exc, args, NULL); - Py_DECREF(args); - if (v != NULL) { - _PyErr_SetObject(tstate, (PyObject *) Py_TYPE(v), v); - Py_DECREF(v); - } - } - LocalFree(s_buf); - return NULL; -} - -PyObject *PyErr_SetExcFromWindowsErrWithFilename( - PyObject *exc, - int ierr, - const char *filename) -{ - PyObject *name = filename ? PyUnicode_DecodeFSDefault(filename) : NULL; - PyObject *ret = PyErr_SetExcFromWindowsErrWithFilenameObjects(exc, - ierr, - name, - NULL); - Py_XDECREF(name); - return ret; -} - -PyObject *PyErr_SetExcFromWindowsErrWithUnicodeFilename( - PyObject *exc, - int ierr, - const Py_UNICODE *filename) -{ - PyObject *name = filename ? PyUnicode_FromWideChar(filename, -1) : NULL; - PyObject *ret = PyErr_SetExcFromWindowsErrWithFilenameObjects(exc, - ierr, - name, - NULL); - Py_XDECREF(name); - return ret; -} - -PyObject *PyErr_SetExcFromWindowsErr(PyObject *exc, int ierr) -{ - return PyErr_SetExcFromWindowsErrWithFilename(exc, ierr, NULL); -} - -PyObject *PyErr_SetFromWindowsErr(int ierr) -{ - return PyErr_SetExcFromWindowsErrWithFilename(PyExc_OSError, - ierr, NULL); -} - -PyObject *PyErr_SetFromWindowsErrWithFilename( - int ierr, - const char *filename) -{ - PyObject *name = filename ? PyUnicode_DecodeFSDefault(filename) : NULL; - PyObject *result = PyErr_SetExcFromWindowsErrWithFilenameObjects( - PyExc_OSError, - ierr, name, NULL); - Py_XDECREF(name); - return result; -} - -PyObject *PyErr_SetFromWindowsErrWithUnicodeFilename( - int ierr, - const Py_UNICODE *filename) -{ - PyObject *name = filename ? PyUnicode_FromWideChar(filename, -1) : NULL; - PyObject *result = PyErr_SetExcFromWindowsErrWithFilenameObjects( - PyExc_OSError, - ierr, name, NULL); - Py_XDECREF(name); - return result; -} -#endif /* MS_WINDOWS */ - -PyObject * -PyErr_SetImportErrorSubclass(PyObject *exception, PyObject *msg, - PyObject *name, PyObject *path) -{ - PyThreadState *tstate = _PyThreadState_GET(); - int issubclass; - PyObject *kwargs, *error; - - issubclass = PyObject_IsSubclass(exception, PyExc_ImportError); - if (issubclass < 0) { - return NULL; - } - else if (!issubclass) { - _PyErr_SetString(tstate, PyExc_TypeError, - "expected a subclass of ImportError"); - return NULL; - } - - if (msg == NULL) { - _PyErr_SetString(tstate, PyExc_TypeError, - "expected a message argument"); - return NULL; - } - - if (name == NULL) { - name = Py_None; - } - if (path == NULL) { - path = Py_None; - } - - kwargs = PyDict_New(); - if (kwargs == NULL) { - return NULL; - } - if (PyDict_SetItemString(kwargs, "name", name) < 0) { - goto done; - } - if (PyDict_SetItemString(kwargs, "path", path) < 0) { - goto done; - } - - error = PyObject_VectorcallDict(exception, &msg, 1, kwargs); - if (error != NULL) { - _PyErr_SetObject(tstate, (PyObject *)Py_TYPE(error), error); - Py_DECREF(error); - } - -done: - Py_DECREF(kwargs); - return NULL; -} - -PyObject * -PyErr_SetImportError(PyObject *msg, PyObject *name, PyObject *path) -{ - return PyErr_SetImportErrorSubclass(PyExc_ImportError, msg, name, path); -} - -void -_PyErr_BadInternalCall(const char *filename, int lineno) -{ - PyThreadState *tstate = _PyThreadState_GET(); - _PyErr_Format(tstate, PyExc_SystemError, - "%s:%d: bad argument to internal function", - filename, lineno); -} - -/* Remove the preprocessor macro for PyErr_BadInternalCall() so that we can - export the entry point for existing object code: */ -#undef PyErr_BadInternalCall -void -PyErr_BadInternalCall(void) -{ - assert(0 && "bad argument to internal function"); - PyThreadState *tstate = _PyThreadState_GET(); - _PyErr_SetString(tstate, PyExc_SystemError, - "bad argument to internal function"); -} -#define PyErr_BadInternalCall() _PyErr_BadInternalCall(__FILE__, __LINE__) - - -static PyObject * -_PyErr_FormatV(PyThreadState *tstate, PyObject *exception, - const char *format, va_list vargs) -{ - PyObject* string; - - /* Issue #23571: PyUnicode_FromFormatV() must not be called with an - exception set, it calls arbitrary Python code like PyObject_Repr() */ - _PyErr_Clear(tstate); - - string = PyUnicode_FromFormatV(format, vargs); - - _PyErr_SetObject(tstate, exception, string); - Py_XDECREF(string); - return NULL; -} - - -PyObject * -PyErr_FormatV(PyObject *exception, const char *format, va_list vargs) -{ - PyThreadState *tstate = _PyThreadState_GET(); - return _PyErr_FormatV(tstate, exception, format, vargs); -} - - -PyObject * -_PyErr_Format(PyThreadState *tstate, PyObject *exception, - const char *format, ...) -{ - va_list vargs; -#ifdef HAVE_STDARG_PROTOTYPES - va_start(vargs, format); -#else - va_start(vargs); -#endif - _PyErr_FormatV(tstate, exception, format, vargs); - va_end(vargs); - return NULL; -} - - -PyObject * -PyErr_Format(PyObject *exception, const char *format, ...) -{ - PyThreadState *tstate = _PyThreadState_GET(); - va_list vargs; -#ifdef HAVE_STDARG_PROTOTYPES - va_start(vargs, format); -#else - va_start(vargs); -#endif - _PyErr_FormatV(tstate, exception, format, vargs); - va_end(vargs); - return NULL; -} - - -PyObject * -PyErr_NewException(const char *name, PyObject *base, PyObject *dict) -{ - PyThreadState *tstate = _PyThreadState_GET(); - PyObject *modulename = NULL; - PyObject *mydict = NULL; - PyObject *bases = NULL; - PyObject *result = NULL; - - const char *dot = strrchr(name, '.'); - if (dot == NULL) { - _PyErr_SetString(tstate, PyExc_SystemError, - "PyErr_NewException: name must be module.class"); - return NULL; - } - if (base == NULL) { - base = PyExc_Exception; - } - if (dict == NULL) { - dict = mydict = PyDict_New(); - if (dict == NULL) - goto failure; - } - - int r = _PyDict_ContainsId(dict, &PyId___module__); - if (r < 0) { - goto failure; - } - if (r == 0) { - modulename = PyUnicode_FromStringAndSize(name, - (Py_ssize_t)(dot-name)); - if (modulename == NULL) - goto failure; - if (_PyDict_SetItemId(dict, &PyId___module__, modulename) != 0) - goto failure; - } - if (PyTuple_Check(base)) { - bases = base; - /* INCREF as we create a new ref in the else branch */ - Py_INCREF(bases); - } else { - bases = PyTuple_Pack(1, base); - if (bases == NULL) - goto failure; - } - /* Create a real class. */ - result = PyObject_CallFunction((PyObject *)&PyType_Type, "sOO", - dot+1, bases, dict); - failure: - Py_XDECREF(bases); - Py_XDECREF(mydict); - Py_XDECREF(modulename); - return result; -} - - -/* Create an exception with docstring */ -PyObject * -PyErr_NewExceptionWithDoc(const char *name, const char *doc, - PyObject *base, PyObject *dict) -{ - int result; - PyObject *ret = NULL; - PyObject *mydict = NULL; /* points to the dict only if we create it */ - PyObject *docobj; - - if (dict == NULL) { - dict = mydict = PyDict_New(); - if (dict == NULL) { - return NULL; - } - } - - if (doc != NULL) { - docobj = PyUnicode_FromString(doc); - if (docobj == NULL) - goto failure; - result = PyDict_SetItemString(dict, "__doc__", docobj); - Py_DECREF(docobj); - if (result < 0) - goto failure; - } - - ret = PyErr_NewException(name, base, dict); - failure: - Py_XDECREF(mydict); - return ret; -} - - -PyDoc_STRVAR(UnraisableHookArgs__doc__, -"UnraisableHookArgs\n\ -\n\ -Type used to pass arguments to sys.unraisablehook."); - -static PyTypeObject UnraisableHookArgsType; - -static PyStructSequence_Field UnraisableHookArgs_fields[] = { - {"exc_type", "Exception type"}, - {"exc_value", "Exception value"}, - {"exc_traceback", "Exception traceback"}, - {"err_msg", "Error message"}, - {"object", "Object causing the exception"}, - {0} -}; - -static PyStructSequence_Desc UnraisableHookArgs_desc = { - .name = "UnraisableHookArgs", - .doc = UnraisableHookArgs__doc__, - .fields = UnraisableHookArgs_fields, - .n_in_sequence = 5 -}; - - -PyStatus -_PyErr_InitTypes(void) -{ - if (UnraisableHookArgsType.tp_name == NULL) { - if (PyStructSequence_InitType2(&UnraisableHookArgsType, - &UnraisableHookArgs_desc) < 0) { - return _PyStatus_ERR("failed to initialize UnraisableHookArgs type"); - } - } - return _PyStatus_OK(); -} - - -static PyObject * -make_unraisable_hook_args(PyThreadState *tstate, PyObject *exc_type, - PyObject *exc_value, PyObject *exc_tb, - PyObject *err_msg, PyObject *obj) -{ - PyObject *args = PyStructSequence_New(&UnraisableHookArgsType); - if (args == NULL) { - return NULL; - } - - Py_ssize_t pos = 0; -#define ADD_ITEM(exc_type) \ - do { \ - if (exc_type == NULL) { \ - exc_type = Py_None; \ - } \ - Py_INCREF(exc_type); \ - PyStructSequence_SET_ITEM(args, pos++, exc_type); \ - } while (0) - - - ADD_ITEM(exc_type); - ADD_ITEM(exc_value); - ADD_ITEM(exc_tb); - ADD_ITEM(err_msg); - ADD_ITEM(obj); -#undef ADD_ITEM - - if (_PyErr_Occurred(tstate)) { - Py_DECREF(args); - return NULL; - } - return args; -} - - - -/* Default implementation of sys.unraisablehook. - - It can be called to log the exception of a custom sys.unraisablehook. - - Do nothing if sys.stderr attribute doesn't exist or is set to None. */ -static int -write_unraisable_exc_file(PyThreadState *tstate, PyObject *exc_type, - PyObject *exc_value, PyObject *exc_tb, - PyObject *err_msg, PyObject *obj, PyObject *file) -{ - if (obj != NULL && obj != Py_None) { - if (err_msg != NULL && err_msg != Py_None) { - if (PyFile_WriteObject(err_msg, file, Py_PRINT_RAW) < 0) { - return -1; - } - if (PyFile_WriteString(": ", file) < 0) { - return -1; - } - } - else { - if (PyFile_WriteString("Exception ignored in: ", file) < 0) { - return -1; - } - } - - if (PyFile_WriteObject(obj, file, 0) < 0) { - _PyErr_Clear(tstate); - if (PyFile_WriteString("<object repr() failed>", file) < 0) { - return -1; - } - } - if (PyFile_WriteString("\n", file) < 0) { - return -1; - } - } - else if (err_msg != NULL && err_msg != Py_None) { - if (PyFile_WriteObject(err_msg, file, Py_PRINT_RAW) < 0) { - return -1; - } - if (PyFile_WriteString(":\n", file) < 0) { - return -1; - } - } - - if (exc_tb != NULL && exc_tb != Py_None) { - if (PyTraceBack_Print(exc_tb, file) < 0) { - /* continue even if writing the traceback failed */ - _PyErr_Clear(tstate); - } - } - - if (exc_type == NULL || exc_type == Py_None) { - return -1; - } - - assert(PyExceptionClass_Check(exc_type)); - - PyObject *modulename = _PyObject_GetAttrId(exc_type, &PyId___module__); - if (modulename == NULL || !PyUnicode_Check(modulename)) { - Py_XDECREF(modulename); - _PyErr_Clear(tstate); - if (PyFile_WriteString("<unknown>", file) < 0) { - return -1; - } - } - else { - if (!_PyUnicode_EqualToASCIIId(modulename, &PyId_builtins)) { - if (PyFile_WriteObject(modulename, file, Py_PRINT_RAW) < 0) { - Py_DECREF(modulename); - return -1; - } - Py_DECREF(modulename); - if (PyFile_WriteString(".", file) < 0) { - return -1; - } - } - else { - Py_DECREF(modulename); - } - } - - PyObject *qualname = _PyType_GetQualName((PyTypeObject *)exc_type); - if (qualname == NULL || !PyUnicode_Check(qualname)) { - Py_XDECREF(qualname); - _PyErr_Clear(tstate); - if (PyFile_WriteString("<unknown>", file) < 0) { - return -1; - } - } - else { - if (PyFile_WriteObject(qualname, file, Py_PRINT_RAW) < 0) { - Py_DECREF(qualname); - return -1; - } - Py_DECREF(qualname); - } - - if (exc_value && exc_value != Py_None) { - if (PyFile_WriteString(": ", file) < 0) { - return -1; - } - if (PyFile_WriteObject(exc_value, file, Py_PRINT_RAW) < 0) { - _PyErr_Clear(tstate); - if (PyFile_WriteString("<exception str() failed>", file) < 0) { - return -1; - } - } - } - - if (PyFile_WriteString("\n", file) < 0) { - return -1; - } - - /* Explicitly call file.flush() */ - PyObject *res = _PyObject_CallMethodIdNoArgs(file, &PyId_flush); - if (!res) { - return -1; - } - Py_DECREF(res); - - return 0; -} - - -static int -write_unraisable_exc(PyThreadState *tstate, PyObject *exc_type, - PyObject *exc_value, PyObject *exc_tb, PyObject *err_msg, - PyObject *obj) -{ - PyObject *file = _PySys_GetObjectId(&PyId_stderr); - if (file == NULL || file == Py_None) { - return 0; - } - - /* Hold a strong reference to ensure that sys.stderr doesn't go away - while we use it */ - Py_INCREF(file); - int res = write_unraisable_exc_file(tstate, exc_type, exc_value, exc_tb, - err_msg, obj, file); - Py_DECREF(file); - - return res; -} - - -PyObject* -_PyErr_WriteUnraisableDefaultHook(PyObject *args) -{ - PyThreadState *tstate = _PyThreadState_GET(); - - if (!Py_IS_TYPE(args, &UnraisableHookArgsType)) { - _PyErr_SetString(tstate, PyExc_TypeError, - "sys.unraisablehook argument type " - "must be UnraisableHookArgs"); - return NULL; - } - - /* Borrowed references */ - PyObject *exc_type = PyStructSequence_GET_ITEM(args, 0); - PyObject *exc_value = PyStructSequence_GET_ITEM(args, 1); - PyObject *exc_tb = PyStructSequence_GET_ITEM(args, 2); - PyObject *err_msg = PyStructSequence_GET_ITEM(args, 3); - PyObject *obj = PyStructSequence_GET_ITEM(args, 4); - - if (write_unraisable_exc(tstate, exc_type, exc_value, exc_tb, err_msg, obj) < 0) { - return NULL; - } - Py_RETURN_NONE; -} - - -/* Call sys.unraisablehook(). - - This function can be used when an exception has occurred but there is no way - for Python to handle it. For example, when a destructor raises an exception - or during garbage collection (gc.collect()). - - If err_msg_str is non-NULL, the error message is formatted as: - "Exception ignored %s" % err_msg_str. Otherwise, use "Exception ignored in" - error message. - - An exception must be set when calling this function. */ -void -_PyErr_WriteUnraisableMsg(const char *err_msg_str, PyObject *obj) -{ - PyThreadState *tstate = _PyThreadState_GET(); - _Py_EnsureTstateNotNULL(tstate); - - PyObject *err_msg = NULL; - PyObject *exc_type, *exc_value, *exc_tb; - _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb); - - assert(exc_type != NULL); - - if (exc_type == NULL) { - /* sys.unraisablehook requires that at least exc_type is set */ - goto default_hook; - } - - if (exc_tb == NULL) { - PyFrameObject *frame = tstate->frame; - if (frame != NULL) { - exc_tb = _PyTraceBack_FromFrame(NULL, frame); - if (exc_tb == NULL) { - _PyErr_Clear(tstate); - } - } - } - - _PyErr_NormalizeException(tstate, &exc_type, &exc_value, &exc_tb); - - if (exc_tb != NULL && exc_tb != Py_None && PyTraceBack_Check(exc_tb)) { - if (PyException_SetTraceback(exc_value, exc_tb) < 0) { - _PyErr_Clear(tstate); - } - } - - if (err_msg_str != NULL) { - err_msg = PyUnicode_FromFormat("Exception ignored %s", err_msg_str); - if (err_msg == NULL) { - PyErr_Clear(); - } - } - - PyObject *hook_args = make_unraisable_hook_args( - tstate, exc_type, exc_value, exc_tb, err_msg, obj); - if (hook_args == NULL) { - err_msg_str = ("Exception ignored on building " - "sys.unraisablehook arguments"); - goto error; - } - - _Py_IDENTIFIER(unraisablehook); - PyObject *hook = _PySys_GetObjectId(&PyId_unraisablehook); - if (hook == NULL) { - Py_DECREF(hook_args); - goto default_hook; - } - - if (_PySys_Audit(tstate, "sys.unraisablehook", "OO", hook, hook_args) < 0) { - Py_DECREF(hook_args); - err_msg_str = "Exception ignored in audit hook"; - obj = NULL; - goto error; - } - - if (hook == Py_None) { - Py_DECREF(hook_args); - goto default_hook; - } - - PyObject *res = PyObject_CallOneArg(hook, hook_args); - Py_DECREF(hook_args); - if (res != NULL) { - Py_DECREF(res); - goto done; - } - - /* sys.unraisablehook failed: log its error using default hook */ - obj = hook; - err_msg_str = NULL; - -error: - /* err_msg_str and obj have been updated and we have a new exception */ - Py_XSETREF(err_msg, PyUnicode_FromString(err_msg_str ? - err_msg_str : "Exception ignored in sys.unraisablehook")); - Py_XDECREF(exc_type); - Py_XDECREF(exc_value); - Py_XDECREF(exc_tb); - _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb); - -default_hook: - /* Call the default unraisable hook (ignore failure) */ - (void)write_unraisable_exc(tstate, exc_type, exc_value, exc_tb, - err_msg, obj); - -done: - Py_XDECREF(exc_type); - Py_XDECREF(exc_value); - Py_XDECREF(exc_tb); - Py_XDECREF(err_msg); - _PyErr_Clear(tstate); /* Just in case */ -} - - -void -PyErr_WriteUnraisable(PyObject *obj) -{ - _PyErr_WriteUnraisableMsg(NULL, obj); -} - - -void -PyErr_SyntaxLocation(const char *filename, int lineno) -{ - PyErr_SyntaxLocationEx(filename, lineno, -1); -} - - -/* Set file and line information for the current exception. - If the exception is not a SyntaxError, also sets additional attributes - to make printing of exceptions believe it is a syntax error. */ - -static void -PyErr_SyntaxLocationObjectEx(PyObject *filename, int lineno, int col_offset, - int end_lineno, int end_col_offset) -{ - PyObject *exc, *v, *tb, *tmp; - _Py_IDENTIFIER(filename); - _Py_IDENTIFIER(lineno); - _Py_IDENTIFIER(end_lineno); - _Py_IDENTIFIER(msg); - _Py_IDENTIFIER(offset); - _Py_IDENTIFIER(end_offset); - _Py_IDENTIFIER(print_file_and_line); - _Py_IDENTIFIER(text); - PyThreadState *tstate = _PyThreadState_GET(); - - /* add attributes for the line number and filename for the error */ - _PyErr_Fetch(tstate, &exc, &v, &tb); - _PyErr_NormalizeException(tstate, &exc, &v, &tb); - /* XXX check that it is, indeed, a syntax error. It might not - * be, though. */ - tmp = PyLong_FromLong(lineno); - if (tmp == NULL) - _PyErr_Clear(tstate); - else { - if (_PyObject_SetAttrId(v, &PyId_lineno, tmp)) { - _PyErr_Clear(tstate); - } - Py_DECREF(tmp); - } - tmp = NULL; - if (col_offset >= 0) { - tmp = PyLong_FromLong(col_offset); - if (tmp == NULL) { - _PyErr_Clear(tstate); - } - } - if (_PyObject_SetAttrId(v, &PyId_offset, tmp ? tmp : Py_None)) { - _PyErr_Clear(tstate); - } - Py_XDECREF(tmp); - - tmp = NULL; - if (end_lineno >= 0) { - tmp = PyLong_FromLong(end_lineno); - if (tmp == NULL) { - _PyErr_Clear(tstate); - } - } - if (_PyObject_SetAttrId(v, &PyId_end_lineno, tmp ? tmp : Py_None)) { - _PyErr_Clear(tstate); - } - Py_XDECREF(tmp); - - tmp = NULL; - if (end_col_offset >= 0) { - tmp = PyLong_FromLong(end_col_offset); - if (tmp == NULL) { - _PyErr_Clear(tstate); - } - } - if (_PyObject_SetAttrId(v, &PyId_end_offset, tmp ? tmp : Py_None)) { - _PyErr_Clear(tstate); - } - Py_XDECREF(tmp); - - tmp = NULL; - if (filename != NULL) { - if (_PyObject_SetAttrId(v, &PyId_filename, filename)) { - _PyErr_Clear(tstate); - } - - tmp = PyErr_ProgramTextObject(filename, lineno); - if (tmp) { - if (_PyObject_SetAttrId(v, &PyId_text, tmp)) { - _PyErr_Clear(tstate); - } - Py_DECREF(tmp); - } - else { - _PyErr_Clear(tstate); - } - } - if (exc != PyExc_SyntaxError) { - if (_PyObject_LookupAttrId(v, &PyId_msg, &tmp) < 0) { - _PyErr_Clear(tstate); - } - else if (tmp) { - Py_DECREF(tmp); - } - else { - tmp = PyObject_Str(v); - if (tmp) { - if (_PyObject_SetAttrId(v, &PyId_msg, tmp)) { - _PyErr_Clear(tstate); - } - Py_DECREF(tmp); - } - else { - _PyErr_Clear(tstate); - } - } - if (_PyObject_LookupAttrId(v, &PyId_print_file_and_line, &tmp) < 0) { - _PyErr_Clear(tstate); - } - else if (tmp) { - Py_DECREF(tmp); - } - else { - if (_PyObject_SetAttrId(v, &PyId_print_file_and_line, - Py_None)) { - _PyErr_Clear(tstate); - } - } - } - _PyErr_Restore(tstate, exc, v, tb); -} - -void -PyErr_SyntaxLocationObject(PyObject *filename, int lineno, int col_offset) { - PyErr_SyntaxLocationObjectEx(filename, lineno, col_offset, lineno, -1); -} - -void -PyErr_RangedSyntaxLocationObject(PyObject *filename, int lineno, int col_offset, - int end_lineno, int end_col_offset) { - PyErr_SyntaxLocationObjectEx(filename, lineno, col_offset, end_lineno, end_col_offset); -} - -void -PyErr_SyntaxLocationEx(const char *filename, int lineno, int col_offset) -{ - PyThreadState *tstate = _PyThreadState_GET(); - PyObject *fileobj; - if (filename != NULL) { - fileobj = PyUnicode_DecodeFSDefault(filename); - if (fileobj == NULL) { - _PyErr_Clear(tstate); - } - } - else { - fileobj = NULL; - } - PyErr_SyntaxLocationObject(fileobj, lineno, col_offset); - Py_XDECREF(fileobj); -} - -/* Attempt to load the line of text that the exception refers to. If it - fails, it will return NULL but will not set an exception. - - XXX The functionality of this function is quite similar to the - functionality in tb_displayline() in traceback.c. */ - -static PyObject * -err_programtext(PyThreadState *tstate, FILE *fp, int lineno, const char* encoding) -{ - int i; - char linebuf[1000]; - if (fp == NULL) { - return NULL; - } - - for (i = 0; i < lineno; i++) { - char *pLastChar = &linebuf[sizeof(linebuf) - 2]; - do { - *pLastChar = '\0'; - if (Py_UniversalNewlineFgets(linebuf, sizeof linebuf, - fp, NULL) == NULL) { - goto after_loop; - } - /* fgets read *something*; if it didn't get as - far as pLastChar, it must have found a newline - or hit the end of the file; if pLastChar is \n, - it obviously found a newline; else we haven't - yet seen a newline, so must continue */ - } while (*pLastChar != '\0' && *pLastChar != '\n'); - } - -after_loop: - fclose(fp); - if (i == lineno) { - PyObject *res; - if (encoding != NULL) { - res = PyUnicode_Decode(linebuf, strlen(linebuf), encoding, "replace"); - } else { - res = PyUnicode_FromString(linebuf); - } - if (res == NULL) - _PyErr_Clear(tstate); - return res; - } - return NULL; -} - -PyObject * -PyErr_ProgramText(const char *filename, int lineno) -{ - if (filename == NULL) { - return NULL; - } - - PyObject *filename_obj = PyUnicode_DecodeFSDefault(filename); - if (filename_obj == NULL) { - PyErr_Clear(); - return NULL; - } - PyObject *res = PyErr_ProgramTextObject(filename_obj, lineno); - Py_DECREF(filename_obj); - return res; -} - -PyObject * -_PyErr_ProgramDecodedTextObject(PyObject *filename, int lineno, const char* encoding) -{ - if (filename == NULL || lineno <= 0) { - return NULL; - } - - PyThreadState *tstate = _PyThreadState_GET(); - FILE *fp = _Py_fopen_obj(filename, "r" PY_STDIOTEXTMODE); - if (fp == NULL) { - _PyErr_Clear(tstate); - return NULL; - } - return err_programtext(tstate, fp, lineno, encoding); -} - -PyObject * -PyErr_ProgramTextObject(PyObject *filename, int lineno) -{ - return _PyErr_ProgramDecodedTextObject(filename, lineno, NULL); -} - -#ifdef __cplusplus -} -#endif diff --git a/contrib/tools/python3/src/Python/fileutils.c b/contrib/tools/python3/src/Python/fileutils.c deleted file mode 100644 index 3b53baa00ee..00000000000 --- a/contrib/tools/python3/src/Python/fileutils.c +++ /dev/null @@ -1,2429 +0,0 @@ -#include "Python.h" -#include "pycore_fileutils.h" // fileutils definitions -#include "pycore_runtime.h" // _PyRuntime -#include "osdefs.h" // SEP -#include <locale.h> - -#ifdef MS_WINDOWS -# include <malloc.h> -# include <windows.h> -extern int winerror_to_errno(int); -#endif - -#ifdef HAVE_LANGINFO_H -#include <langinfo.h> -#endif - -#ifdef HAVE_SYS_IOCTL_H -#include <sys/ioctl.h> -#endif - -#ifdef HAVE_NON_UNICODE_WCHAR_T_REPRESENTATION -#include <iconv.h> -#endif - -#ifdef HAVE_FCNTL_H -#include <fcntl.h> -#endif /* HAVE_FCNTL_H */ - -#ifdef O_CLOEXEC -/* Does open() support the O_CLOEXEC flag? Possible values: - - -1: unknown - 0: open() ignores O_CLOEXEC flag, ex: Linux kernel older than 2.6.23 - 1: open() supports O_CLOEXEC flag, close-on-exec is set - - The flag is used by _Py_open(), _Py_open_noraise(), io.FileIO - and os.open(). */ -int _Py_open_cloexec_works = -1; -#endif - -// The value must be the same in unicodeobject.c. -#define MAX_UNICODE 0x10ffff - -// mbstowcs() and mbrtowc() errors -static const size_t DECODE_ERROR = ((size_t)-1); -static const size_t INCOMPLETE_CHARACTER = (size_t)-2; - - -static int -get_surrogateescape(_Py_error_handler errors, int *surrogateescape) -{ - switch (errors) - { - case _Py_ERROR_STRICT: - *surrogateescape = 0; - return 0; - case _Py_ERROR_SURROGATEESCAPE: - *surrogateescape = 1; - return 0; - default: - return -1; - } -} - - -PyObject * -_Py_device_encoding(int fd) -{ - int valid; - Py_BEGIN_ALLOW_THREADS - _Py_BEGIN_SUPPRESS_IPH - valid = isatty(fd); - _Py_END_SUPPRESS_IPH - Py_END_ALLOW_THREADS - if (!valid) - Py_RETURN_NONE; - -#if defined(MS_WINDOWS) - UINT cp; - if (fd == 0) - cp = GetConsoleCP(); - else if (fd == 1 || fd == 2) - cp = GetConsoleOutputCP(); - else - cp = 0; - /* GetConsoleCP() and GetConsoleOutputCP() return 0 if the application - has no console */ - if (cp == 0) { - Py_RETURN_NONE; - } - - return PyUnicode_FromFormat("cp%u", (unsigned int)cp); -#else - return _Py_GetLocaleEncodingObject(); -#endif -} - - -static size_t -is_valid_wide_char(wchar_t ch) -{ -#ifdef HAVE_NON_UNICODE_WCHAR_T_REPRESENTATION - /* Oracle Solaris doesn't use Unicode code points as wchar_t encoding - for non-Unicode locales, which makes values higher than MAX_UNICODE - possibly valid. */ - return 1; -#endif - if (Py_UNICODE_IS_SURROGATE(ch)) { - // Reject lone surrogate characters - return 0; - } - if (ch > MAX_UNICODE) { - // bpo-35883: Reject characters outside [U+0000; U+10ffff] range. - // The glibc mbstowcs() UTF-8 decoder does not respect the RFC 3629, - // it creates characters outside the [U+0000; U+10ffff] range: - // https://sourceware.org/bugzilla/show_bug.cgi?id=2373 - return 0; - } - return 1; -} - - -static size_t -_Py_mbstowcs(wchar_t *dest, const char *src, size_t n) -{ - size_t count = mbstowcs(dest, src, n); - if (dest != NULL && count != DECODE_ERROR) { - for (size_t i=0; i < count; i++) { - wchar_t ch = dest[i]; - if (!is_valid_wide_char(ch)) { - return DECODE_ERROR; - } - } - } - return count; -} - - -#ifdef HAVE_MBRTOWC -static size_t -_Py_mbrtowc(wchar_t *pwc, const char *str, size_t len, mbstate_t *pmbs) -{ - assert(pwc != NULL); - size_t count = mbrtowc(pwc, str, len, pmbs); - if (count != 0 && count != DECODE_ERROR && count != INCOMPLETE_CHARACTER) { - if (!is_valid_wide_char(*pwc)) { - return DECODE_ERROR; - } - } - return count; -} -#endif - - -#if !defined(_Py_FORCE_UTF8_FS_ENCODING) && !defined(MS_WINDOWS) - -#define USE_FORCE_ASCII - -extern int _Py_normalize_encoding(const char *, char *, size_t); - -/* Workaround FreeBSD and OpenIndiana locale encoding issue with the C locale - and POSIX locale. nl_langinfo(CODESET) announces an alias of the - ASCII encoding, whereas mbstowcs() and wcstombs() functions use the - ISO-8859-1 encoding. The problem is that os.fsencode() and os.fsdecode() use - locale.getpreferredencoding() codec. For example, if command line arguments - are decoded by mbstowcs() and encoded back by os.fsencode(), we get a - UnicodeEncodeError instead of retrieving the original byte string. - - The workaround is enabled if setlocale(LC_CTYPE, NULL) returns "C", - nl_langinfo(CODESET) announces "ascii" (or an alias to ASCII), and at least - one byte in range 0x80-0xff can be decoded from the locale encoding. The - workaround is also enabled on error, for example if getting the locale - failed. - - On HP-UX with the C locale or the POSIX locale, nl_langinfo(CODESET) - announces "roman8" but mbstowcs() uses Latin1 in practice. Force also the - ASCII encoding in this case. - - Values of force_ascii: - - 1: the workaround is used: Py_EncodeLocale() uses - encode_ascii_surrogateescape() and Py_DecodeLocale() uses - decode_ascii() - 0: the workaround is not used: Py_EncodeLocale() uses wcstombs() and - Py_DecodeLocale() uses mbstowcs() - -1: unknown, need to call check_force_ascii() to get the value -*/ -static int force_ascii = -1; - -static int -check_force_ascii(void) -{ - char *loc = setlocale(LC_CTYPE, NULL); - if (loc == NULL) { - goto error; - } - if (strcmp(loc, "C") != 0 && strcmp(loc, "POSIX") != 0) { - /* the LC_CTYPE locale is different than C and POSIX */ - return 0; - } - -#if defined(HAVE_LANGINFO_H) && defined(CODESET) - const char *codeset = nl_langinfo(CODESET); - if (!codeset || codeset[0] == '\0') { - /* CODESET is not set or empty */ - goto error; - } - - char encoding[20]; /* longest name: "iso_646.irv_1991\0" */ - if (!_Py_normalize_encoding(codeset, encoding, sizeof(encoding))) { - goto error; - } - -#ifdef __hpux - if (strcmp(encoding, "roman8") == 0) { - unsigned char ch; - wchar_t wch; - size_t res; - - ch = (unsigned char)0xA7; - res = _Py_mbstowcs(&wch, (char*)&ch, 1); - if (res != DECODE_ERROR && wch == L'\xA7') { - /* On HP-UX with C locale or the POSIX locale, - nl_langinfo(CODESET) announces "roman8", whereas mbstowcs() uses - Latin1 encoding in practice. Force ASCII in this case. - - Roman8 decodes 0xA7 to U+00CF. Latin1 decodes 0xA7 to U+00A7. */ - return 1; - } - } -#else - const char* ascii_aliases[] = { - "ascii", - /* Aliases from Lib/encodings/aliases.py */ - "646", - "ansi_x3.4_1968", - "ansi_x3.4_1986", - "ansi_x3_4_1968", - "cp367", - "csascii", - "ibm367", - "iso646_us", - "iso_646.irv_1991", - "iso_ir_6", - "us", - "us_ascii", - NULL - }; - - int is_ascii = 0; - for (const char **alias=ascii_aliases; *alias != NULL; alias++) { - if (strcmp(encoding, *alias) == 0) { - is_ascii = 1; - break; - } - } - if (!is_ascii) { - /* nl_langinfo(CODESET) is not "ascii" or an alias of ASCII */ - return 0; - } - - for (unsigned int i=0x80; i<=0xff; i++) { - char ch[1]; - wchar_t wch[1]; - size_t res; - - unsigned uch = (unsigned char)i; - ch[0] = (char)uch; - res = _Py_mbstowcs(wch, ch, 1); - if (res != DECODE_ERROR) { - /* decoding a non-ASCII character from the locale encoding succeed: - the locale encoding is not ASCII, force ASCII */ - return 1; - } - } - /* None of the bytes in the range 0x80-0xff can be decoded from the locale - encoding: the locale encoding is really ASCII */ -#endif /* !defined(__hpux) */ - return 0; -#else - /* nl_langinfo(CODESET) is not available: always force ASCII */ - return 1; -#endif /* defined(HAVE_LANGINFO_H) && defined(CODESET) */ - -error: - /* if an error occurred, force the ASCII encoding */ - return 1; -} - - -int -_Py_GetForceASCII(void) -{ - if (force_ascii == -1) { - force_ascii = check_force_ascii(); - } - return force_ascii; -} - - -void -_Py_ResetForceASCII(void) -{ - force_ascii = -1; -} - - -static int -encode_ascii(const wchar_t *text, char **str, - size_t *error_pos, const char **reason, - int raw_malloc, _Py_error_handler errors) -{ - char *result = NULL, *out; - size_t len, i; - wchar_t ch; - - int surrogateescape; - if (get_surrogateescape(errors, &surrogateescape) < 0) { - return -3; - } - - len = wcslen(text); - - /* +1 for NULL byte */ - if (raw_malloc) { - result = PyMem_RawMalloc(len + 1); - } - else { - result = PyMem_Malloc(len + 1); - } - if (result == NULL) { - return -1; - } - - out = result; - for (i=0; i<len; i++) { - ch = text[i]; - - if (ch <= 0x7f) { - /* ASCII character */ - *out++ = (char)ch; - } - else if (surrogateescape && 0xdc80 <= ch && ch <= 0xdcff) { - /* UTF-8b surrogate */ - *out++ = (char)(ch - 0xdc00); - } - else { - if (raw_malloc) { - PyMem_RawFree(result); - } - else { - PyMem_Free(result); - } - if (error_pos != NULL) { - *error_pos = i; - } - if (reason) { - *reason = "encoding error"; - } - return -2; - } - } - *out = '\0'; - *str = result; - return 0; -} -#else -int -_Py_GetForceASCII(void) -{ - return 0; -} - -void -_Py_ResetForceASCII(void) -{ - /* nothing to do */ -} -#endif /* !defined(_Py_FORCE_UTF8_FS_ENCODING) && !defined(MS_WINDOWS) */ - - -#if !defined(HAVE_MBRTOWC) || defined(USE_FORCE_ASCII) -static int -decode_ascii(const char *arg, wchar_t **wstr, size_t *wlen, - const char **reason, _Py_error_handler errors) -{ - wchar_t *res; - unsigned char *in; - wchar_t *out; - size_t argsize = strlen(arg) + 1; - - int surrogateescape; - if (get_surrogateescape(errors, &surrogateescape) < 0) { - return -3; - } - - if (argsize > PY_SSIZE_T_MAX / sizeof(wchar_t)) { - return -1; - } - res = PyMem_RawMalloc(argsize * sizeof(wchar_t)); - if (!res) { - return -1; - } - - out = res; - for (in = (unsigned char*)arg; *in; in++) { - unsigned char ch = *in; - if (ch < 128) { - *out++ = ch; - } - else { - if (!surrogateescape) { - PyMem_RawFree(res); - if (wlen) { - *wlen = in - (unsigned char*)arg; - } - if (reason) { - *reason = "decoding error"; - } - return -2; - } - *out++ = 0xdc00 + ch; - } - } - *out = 0; - - if (wlen != NULL) { - *wlen = out - res; - } - *wstr = res; - return 0; -} -#endif /* !HAVE_MBRTOWC */ - -static int -decode_current_locale(const char* arg, wchar_t **wstr, size_t *wlen, - const char **reason, _Py_error_handler errors) -{ - wchar_t *res; - size_t argsize; - size_t count; -#ifdef HAVE_MBRTOWC - unsigned char *in; - wchar_t *out; - mbstate_t mbs; -#endif - - int surrogateescape; - if (get_surrogateescape(errors, &surrogateescape) < 0) { - return -3; - } - -#ifdef HAVE_BROKEN_MBSTOWCS - /* Some platforms have a broken implementation of - * mbstowcs which does not count the characters that - * would result from conversion. Use an upper bound. - */ - argsize = strlen(arg); -#else - argsize = _Py_mbstowcs(NULL, arg, 0); -#endif - if (argsize != DECODE_ERROR) { - if (argsize > PY_SSIZE_T_MAX / sizeof(wchar_t) - 1) { - return -1; - } - res = (wchar_t *)PyMem_RawMalloc((argsize + 1) * sizeof(wchar_t)); - if (!res) { - return -1; - } - - count = _Py_mbstowcs(res, arg, argsize + 1); - if (count != DECODE_ERROR) { - *wstr = res; - if (wlen != NULL) { - *wlen = count; - } - return 0; - } - PyMem_RawFree(res); - } - - /* Conversion failed. Fall back to escaping with surrogateescape. */ -#ifdef HAVE_MBRTOWC - /* Try conversion with mbrtwoc (C99), and escape non-decodable bytes. */ - - /* Overallocate; as multi-byte characters are in the argument, the - actual output could use less memory. */ - argsize = strlen(arg) + 1; - if (argsize > PY_SSIZE_T_MAX / sizeof(wchar_t)) { - return -1; - } - res = (wchar_t*)PyMem_RawMalloc(argsize * sizeof(wchar_t)); - if (!res) { - return -1; - } - - in = (unsigned char*)arg; - out = res; - memset(&mbs, 0, sizeof mbs); - while (argsize) { - size_t converted = _Py_mbrtowc(out, (char*)in, argsize, &mbs); - if (converted == 0) { - /* Reached end of string; null char stored. */ - break; - } - - if (converted == INCOMPLETE_CHARACTER) { - /* Incomplete character. This should never happen, - since we provide everything that we have - - unless there is a bug in the C library, or I - misunderstood how mbrtowc works. */ - goto decode_error; - } - - if (converted == DECODE_ERROR) { - if (!surrogateescape) { - goto decode_error; - } - - /* Decoding error. Escape as UTF-8b, and start over in the initial - shift state. */ - *out++ = 0xdc00 + *in++; - argsize--; - memset(&mbs, 0, sizeof mbs); - continue; - } - - // _Py_mbrtowc() reject lone surrogate characters - assert(!Py_UNICODE_IS_SURROGATE(*out)); - - /* successfully converted some bytes */ - in += converted; - argsize -= converted; - out++; - } - if (wlen != NULL) { - *wlen = out - res; - } - *wstr = res; - return 0; - -decode_error: - PyMem_RawFree(res); - if (wlen) { - *wlen = in - (unsigned char*)arg; - } - if (reason) { - *reason = "decoding error"; - } - return -2; -#else /* HAVE_MBRTOWC */ - /* Cannot use C locale for escaping; manually escape as if charset - is ASCII (i.e. escape all bytes > 128. This will still roundtrip - correctly in the locale's charset, which must be an ASCII superset. */ - return decode_ascii(arg, wstr, wlen, reason, errors); -#endif /* HAVE_MBRTOWC */ -} - - -/* Decode a byte string from the locale encoding. - - Use the strict error handler if 'surrogateescape' is zero. Use the - surrogateescape error handler if 'surrogateescape' is non-zero: undecodable - bytes are decoded as characters in range U+DC80..U+DCFF. If a byte sequence - can be decoded as a surrogate character, escape the bytes using the - surrogateescape error handler instead of decoding them. - - On success, return 0 and write the newly allocated wide character string into - *wstr (use PyMem_RawFree() to free the memory). If wlen is not NULL, write - the number of wide characters excluding the null character into *wlen. - - On memory allocation failure, return -1. - - On decoding error, return -2. If wlen is not NULL, write the start of - invalid byte sequence in the input string into *wlen. If reason is not NULL, - write the decoding error message into *reason. - - Return -3 if the error handler 'errors' is not supported. - - Use the Py_EncodeLocaleEx() function to encode the character string back to - a byte string. */ -int -_Py_DecodeLocaleEx(const char* arg, wchar_t **wstr, size_t *wlen, - const char **reason, - int current_locale, _Py_error_handler errors) -{ - if (current_locale) { -#ifdef _Py_FORCE_UTF8_LOCALE - return _Py_DecodeUTF8Ex(arg, strlen(arg), wstr, wlen, reason, - errors); -#else - return decode_current_locale(arg, wstr, wlen, reason, errors); -#endif - } - -#ifdef _Py_FORCE_UTF8_FS_ENCODING - return _Py_DecodeUTF8Ex(arg, strlen(arg), wstr, wlen, reason, - errors); -#else - int use_utf8 = (Py_UTF8Mode == 1); -#ifdef MS_WINDOWS - use_utf8 |= !Py_LegacyWindowsFSEncodingFlag; -#endif - if (use_utf8) { - return _Py_DecodeUTF8Ex(arg, strlen(arg), wstr, wlen, reason, - errors); - } - -#ifdef USE_FORCE_ASCII - if (force_ascii == -1) { - force_ascii = check_force_ascii(); - } - - if (force_ascii) { - /* force ASCII encoding to workaround mbstowcs() issue */ - return decode_ascii(arg, wstr, wlen, reason, errors); - } -#endif - - return decode_current_locale(arg, wstr, wlen, reason, errors); -#endif /* !_Py_FORCE_UTF8_FS_ENCODING */ -} - - -/* Decode a byte string from the locale encoding with the - surrogateescape error handler: undecodable bytes are decoded as characters - in range U+DC80..U+DCFF. If a byte sequence can be decoded as a surrogate - character, escape the bytes using the surrogateescape error handler instead - of decoding them. - - Return a pointer to a newly allocated wide character string, use - PyMem_RawFree() to free the memory. If size is not NULL, write the number of - wide characters excluding the null character into *size - - Return NULL on decoding error or memory allocation error. If *size* is not - NULL, *size is set to (size_t)-1 on memory error or set to (size_t)-2 on - decoding error. - - Decoding errors should never happen, unless there is a bug in the C - library. - - Use the Py_EncodeLocale() function to encode the character string back to a - byte string. */ -wchar_t* -Py_DecodeLocale(const char* arg, size_t *wlen) -{ - wchar_t *wstr; - int res = _Py_DecodeLocaleEx(arg, &wstr, wlen, - NULL, 0, - _Py_ERROR_SURROGATEESCAPE); - if (res != 0) { - assert(res != -3); - if (wlen != NULL) { - *wlen = (size_t)res; - } - return NULL; - } - return wstr; -} - - -static int -encode_current_locale(const wchar_t *text, char **str, - size_t *error_pos, const char **reason, - int raw_malloc, _Py_error_handler errors) -{ - const size_t len = wcslen(text); - char *result = NULL, *bytes = NULL; - size_t i, size, converted; - wchar_t c, buf[2]; - - int surrogateescape; - if (get_surrogateescape(errors, &surrogateescape) < 0) { - return -3; - } - - /* The function works in two steps: - 1. compute the length of the output buffer in bytes (size) - 2. outputs the bytes */ - size = 0; - buf[1] = 0; - while (1) { - for (i=0; i < len; i++) { - c = text[i]; - if (c >= 0xdc80 && c <= 0xdcff) { - if (!surrogateescape) { - goto encode_error; - } - /* UTF-8b surrogate */ - if (bytes != NULL) { - *bytes++ = c - 0xdc00; - size--; - } - else { - size++; - } - continue; - } - else { - buf[0] = c; - if (bytes != NULL) { - converted = wcstombs(bytes, buf, size); - } - else { - converted = wcstombs(NULL, buf, 0); - } - if (converted == DECODE_ERROR) { - goto encode_error; - } - if (bytes != NULL) { - bytes += converted; - size -= converted; - } - else { - size += converted; - } - } - } - if (result != NULL) { - *bytes = '\0'; - break; - } - - size += 1; /* nul byte at the end */ - if (raw_malloc) { - result = PyMem_RawMalloc(size); - } - else { - result = PyMem_Malloc(size); - } - if (result == NULL) { - return -1; - } - bytes = result; - } - *str = result; - return 0; - -encode_error: - if (raw_malloc) { - PyMem_RawFree(result); - } - else { - PyMem_Free(result); - } - if (error_pos != NULL) { - *error_pos = i; - } - if (reason) { - *reason = "encoding error"; - } - return -2; -} - - -/* Encode a string to the locale encoding. - - Parameters: - - * raw_malloc: if non-zero, allocate memory using PyMem_RawMalloc() instead - of PyMem_Malloc(). - * current_locale: if non-zero, use the current LC_CTYPE, otherwise use - Python filesystem encoding. - * errors: error handler like "strict" or "surrogateescape". - - Return value: - - 0: success, *str is set to a newly allocated decoded string. - -1: memory allocation failure - -2: encoding error, set *error_pos and *reason (if set). - -3: the error handler 'errors' is not supported. - */ -static int -encode_locale_ex(const wchar_t *text, char **str, size_t *error_pos, - const char **reason, - int raw_malloc, int current_locale, _Py_error_handler errors) -{ - if (current_locale) { -#ifdef _Py_FORCE_UTF8_LOCALE - return _Py_EncodeUTF8Ex(text, str, error_pos, reason, - raw_malloc, errors); -#else - return encode_current_locale(text, str, error_pos, reason, - raw_malloc, errors); -#endif - } - -#ifdef _Py_FORCE_UTF8_FS_ENCODING - return _Py_EncodeUTF8Ex(text, str, error_pos, reason, - raw_malloc, errors); -#else - int use_utf8 = (Py_UTF8Mode == 1); -#ifdef MS_WINDOWS - use_utf8 |= !Py_LegacyWindowsFSEncodingFlag; -#endif - if (use_utf8) { - return _Py_EncodeUTF8Ex(text, str, error_pos, reason, - raw_malloc, errors); - } - -#ifdef USE_FORCE_ASCII - if (force_ascii == -1) { - force_ascii = check_force_ascii(); - } - - if (force_ascii) { - return encode_ascii(text, str, error_pos, reason, - raw_malloc, errors); - } -#endif - - return encode_current_locale(text, str, error_pos, reason, - raw_malloc, errors); -#endif /* _Py_FORCE_UTF8_FS_ENCODING */ -} - -static char* -encode_locale(const wchar_t *text, size_t *error_pos, - int raw_malloc, int current_locale) -{ - char *str; - int res = encode_locale_ex(text, &str, error_pos, NULL, - raw_malloc, current_locale, - _Py_ERROR_SURROGATEESCAPE); - if (res != -2 && error_pos) { - *error_pos = (size_t)-1; - } - if (res != 0) { - return NULL; - } - return str; -} - -/* Encode a wide character string to the locale encoding with the - surrogateescape error handler: surrogate characters in the range - U+DC80..U+DCFF are converted to bytes 0x80..0xFF. - - Return a pointer to a newly allocated byte string, use PyMem_Free() to free - the memory. Return NULL on encoding or memory allocation error. - - If error_pos is not NULL, *error_pos is set to (size_t)-1 on success, or set - to the index of the invalid character on encoding error. - - Use the Py_DecodeLocale() function to decode the bytes string back to a wide - character string. */ -char* -Py_EncodeLocale(const wchar_t *text, size_t *error_pos) -{ - return encode_locale(text, error_pos, 0, 0); -} - - -/* Similar to Py_EncodeLocale(), but result must be freed by PyMem_RawFree() - instead of PyMem_Free(). */ -char* -_Py_EncodeLocaleRaw(const wchar_t *text, size_t *error_pos) -{ - return encode_locale(text, error_pos, 1, 0); -} - - -int -_Py_EncodeLocaleEx(const wchar_t *text, char **str, - size_t *error_pos, const char **reason, - int current_locale, _Py_error_handler errors) -{ - return encode_locale_ex(text, str, error_pos, reason, 1, - current_locale, errors); -} - - -// Get the current locale encoding name: -// -// - Return "UTF-8" if _Py_FORCE_UTF8_LOCALE macro is defined (ex: on Android) -// - Return "UTF-8" if the UTF-8 Mode is enabled -// - On Windows, return the ANSI code page (ex: "cp1250") -// - Return "UTF-8" if nl_langinfo(CODESET) returns an empty string. -// - Otherwise, return nl_langinfo(CODESET). -// -// Return NULL on memory allocation failure. -// -// See also config_get_locale_encoding() -wchar_t* -_Py_GetLocaleEncoding(void) -{ -#ifdef _Py_FORCE_UTF8_LOCALE - // On Android langinfo.h and CODESET are missing, - // and UTF-8 is always used in mbstowcs() and wcstombs(). - return _PyMem_RawWcsdup(L"UTF-8"); -#else - const PyPreConfig *preconfig = &_PyRuntime.preconfig; - if (preconfig->utf8_mode) { - return _PyMem_RawWcsdup(L"UTF-8"); - } - -#ifdef MS_WINDOWS - wchar_t encoding[23]; - unsigned int ansi_codepage = GetACP(); - swprintf(encoding, Py_ARRAY_LENGTH(encoding), L"cp%u", ansi_codepage); - encoding[Py_ARRAY_LENGTH(encoding) - 1] = 0; - return _PyMem_RawWcsdup(encoding); -#else - const char *encoding = nl_langinfo(CODESET); - if (!encoding || encoding[0] == '\0') { - // Use UTF-8 if nl_langinfo() returns an empty string. It can happen on - // macOS if the LC_CTYPE locale is not supported. - return _PyMem_RawWcsdup(L"UTF-8"); - } - - wchar_t *wstr; - int res = decode_current_locale(encoding, &wstr, NULL, - NULL, _Py_ERROR_SURROGATEESCAPE); - if (res < 0) { - return NULL; - } - return wstr; -#endif // !MS_WINDOWS - -#endif // !_Py_FORCE_UTF8_LOCALE -} - - -PyObject * -_Py_GetLocaleEncodingObject(void) -{ - wchar_t *encoding = _Py_GetLocaleEncoding(); - if (encoding == NULL) { - PyErr_NoMemory(); - return NULL; - } - - PyObject *str = PyUnicode_FromWideChar(encoding, -1); - PyMem_RawFree(encoding); - return str; -} - -#ifdef HAVE_NON_UNICODE_WCHAR_T_REPRESENTATION - -/* Check whether current locale uses Unicode as internal wchar_t form. */ -int -_Py_LocaleUsesNonUnicodeWchar(void) -{ - /* Oracle Solaris uses non-Unicode internal wchar_t form for - non-Unicode locales and hence needs conversion to UTF first. */ - char* codeset = nl_langinfo(CODESET); - if (!codeset) { - return 0; - } - /* 646 refers to ISO/IEC 646 standard that corresponds to ASCII encoding */ - return (strcmp(codeset, "UTF-8") != 0 && strcmp(codeset, "646") != 0); -} - -static wchar_t * -_Py_ConvertWCharForm(const wchar_t *source, Py_ssize_t size, - const char *tocode, const char *fromcode) -{ - Py_BUILD_ASSERT(sizeof(wchar_t) == 4); - - /* Ensure we won't overflow the size. */ - if (size > (PY_SSIZE_T_MAX / (Py_ssize_t)sizeof(wchar_t))) { - PyErr_NoMemory(); - return NULL; - } - - /* the string doesn't have to be NULL terminated */ - wchar_t* target = PyMem_Malloc(size * sizeof(wchar_t)); - if (target == NULL) { - PyErr_NoMemory(); - return NULL; - } - - iconv_t cd = iconv_open(tocode, fromcode); - if (cd == (iconv_t)-1) { - PyErr_Format(PyExc_ValueError, "iconv_open() failed"); - PyMem_Free(target); - return NULL; - } - - char *inbuf = (char *) source; - char *outbuf = (char *) target; - size_t inbytesleft = sizeof(wchar_t) * size; - size_t outbytesleft = inbytesleft; - - size_t ret = iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft); - if (ret == DECODE_ERROR) { - PyErr_Format(PyExc_ValueError, "iconv() failed"); - PyMem_Free(target); - iconv_close(cd); - return NULL; - } - - iconv_close(cd); - return target; -} - -/* Convert a wide character string to the UCS-4 encoded string. This - is necessary on systems where internal form of wchar_t are not Unicode - code points (e.g. Oracle Solaris). - - Return a pointer to a newly allocated string, use PyMem_Free() to free - the memory. Return NULL and raise exception on conversion or memory - allocation error. */ -wchar_t * -_Py_DecodeNonUnicodeWchar(const wchar_t *native, Py_ssize_t size) -{ - return _Py_ConvertWCharForm(native, size, "UCS-4-INTERNAL", "wchar_t"); -} - -/* Convert a UCS-4 encoded string to native wide character string. This - is necessary on systems where internal form of wchar_t are not Unicode - code points (e.g. Oracle Solaris). - - The conversion is done in place. This can be done because both wchar_t - and UCS-4 use 4-byte encoding, and one wchar_t symbol always correspond - to a single UCS-4 symbol and vice versa. (This is true for Oracle Solaris, - which is currently the only system using these functions; it doesn't have - to be for other systems). - - Return 0 on success. Return -1 and raise exception on conversion - or memory allocation error. */ -int -_Py_EncodeNonUnicodeWchar_InPlace(wchar_t *unicode, Py_ssize_t size) -{ - wchar_t* result = _Py_ConvertWCharForm(unicode, size, "wchar_t", "UCS-4-INTERNAL"); - if (!result) { - return -1; - } - memcpy(unicode, result, size * sizeof(wchar_t)); - PyMem_Free(result); - return 0; -} -#endif /* HAVE_NON_UNICODE_WCHAR_T_REPRESENTATION */ - -#ifdef MS_WINDOWS -static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */ - -static void -FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, time_t *time_out, int* nsec_out) -{ - /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */ - /* Cannot simply cast and dereference in_ptr, - since it might not be aligned properly */ - __int64 in; - memcpy(&in, in_ptr, sizeof(in)); - *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */ - *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, time_t); -} - -void -_Py_time_t_to_FILE_TIME(time_t time_in, int nsec_in, FILETIME *out_ptr) -{ - /* XXX endianness */ - __int64 out; - out = time_in + secs_between_epochs; - out = out * 10000000 + nsec_in / 100; - memcpy(out_ptr, &out, sizeof(out)); -} - -/* Below, we *know* that ugo+r is 0444 */ -#if _S_IREAD != 0400 -#error Unsupported C library -#endif -static int -attributes_to_mode(DWORD attr) -{ - int m = 0; - if (attr & FILE_ATTRIBUTE_DIRECTORY) - m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */ - else - m |= _S_IFREG; - if (attr & FILE_ATTRIBUTE_READONLY) - m |= 0444; - else - m |= 0666; - return m; -} - -void -_Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, ULONG reparse_tag, - struct _Py_stat_struct *result) -{ - memset(result, 0, sizeof(*result)); - result->st_mode = attributes_to_mode(info->dwFileAttributes); - result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow; - result->st_dev = info->dwVolumeSerialNumber; - result->st_rdev = result->st_dev; - FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec); - FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec); - FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec); - result->st_nlink = info->nNumberOfLinks; - result->st_ino = (((uint64_t)info->nFileIndexHigh) << 32) + info->nFileIndexLow; - /* bpo-37834: Only actual symlinks set the S_IFLNK flag. But lstat() will - open other name surrogate reparse points without traversing them. To - detect/handle these, check st_file_attributes and st_reparse_tag. */ - result->st_reparse_tag = reparse_tag; - if (info->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT && - reparse_tag == IO_REPARSE_TAG_SYMLINK) { - /* first clear the S_IFMT bits */ - result->st_mode ^= (result->st_mode & S_IFMT); - /* now set the bits that make this a symlink */ - result->st_mode |= S_IFLNK; - } - result->st_file_attributes = info->dwFileAttributes; -} -#endif - -/* Return information about a file. - - On POSIX, use fstat(). - - On Windows, use GetFileType() and GetFileInformationByHandle() which support - files larger than 2 GiB. fstat() may fail with EOVERFLOW on files larger - than 2 GiB because the file size type is a signed 32-bit integer: see issue - #23152. - - On Windows, set the last Windows error and return nonzero on error. On - POSIX, set errno and return nonzero on error. Fill status and return 0 on - success. */ -int -_Py_fstat_noraise(int fd, struct _Py_stat_struct *status) -{ -#ifdef MS_WINDOWS - BY_HANDLE_FILE_INFORMATION info; - HANDLE h; - int type; - - h = _Py_get_osfhandle_noraise(fd); - - if (h == INVALID_HANDLE_VALUE) { - /* errno is already set by _get_osfhandle, but we also set - the Win32 error for callers who expect that */ - SetLastError(ERROR_INVALID_HANDLE); - return -1; - } - memset(status, 0, sizeof(*status)); - - type = GetFileType(h); - if (type == FILE_TYPE_UNKNOWN) { - DWORD error = GetLastError(); - if (error != 0) { - errno = winerror_to_errno(error); - return -1; - } - /* else: valid but unknown file */ - } - - if (type != FILE_TYPE_DISK) { - if (type == FILE_TYPE_CHAR) - status->st_mode = _S_IFCHR; - else if (type == FILE_TYPE_PIPE) - status->st_mode = _S_IFIFO; - return 0; - } - - if (!GetFileInformationByHandle(h, &info)) { - /* The Win32 error is already set, but we also set errno for - callers who expect it */ - errno = winerror_to_errno(GetLastError()); - return -1; - } - - _Py_attribute_data_to_stat(&info, 0, status); - /* specific to fstat() */ - status->st_ino = (((uint64_t)info.nFileIndexHigh) << 32) + info.nFileIndexLow; - return 0; -#else - return fstat(fd, status); -#endif -} - -/* Return information about a file. - - On POSIX, use fstat(). - - On Windows, use GetFileType() and GetFileInformationByHandle() which support - files larger than 2 GiB. fstat() may fail with EOVERFLOW on files larger - than 2 GiB because the file size type is a signed 32-bit integer: see issue - #23152. - - Raise an exception and return -1 on error. On Windows, set the last Windows - error on error. On POSIX, set errno on error. Fill status and return 0 on - success. - - Release the GIL to call GetFileType() and GetFileInformationByHandle(), or - to call fstat(). The caller must hold the GIL. */ -int -_Py_fstat(int fd, struct _Py_stat_struct *status) -{ - int res; - - assert(PyGILState_Check()); - - Py_BEGIN_ALLOW_THREADS - res = _Py_fstat_noraise(fd, status); - Py_END_ALLOW_THREADS - - if (res != 0) { -#ifdef MS_WINDOWS - PyErr_SetFromWindowsErr(0); -#else - PyErr_SetFromErrno(PyExc_OSError); -#endif - return -1; - } - return 0; -} - -/* Call _wstat() on Windows, or encode the path to the filesystem encoding and - call stat() otherwise. Only fill st_mode attribute on Windows. - - Return 0 on success, -1 on _wstat() / stat() error, -2 if an exception was - raised. */ - -int -_Py_stat(PyObject *path, struct stat *statbuf) -{ -#ifdef MS_WINDOWS - int err; - struct _stat wstatbuf; - -#if USE_UNICODE_WCHAR_CACHE - const wchar_t *wpath = _PyUnicode_AsUnicode(path); -#else /* USE_UNICODE_WCHAR_CACHE */ - wchar_t *wpath = PyUnicode_AsWideCharString(path, NULL); -#endif /* USE_UNICODE_WCHAR_CACHE */ - if (wpath == NULL) - return -2; - - err = _wstat(wpath, &wstatbuf); - if (!err) - statbuf->st_mode = wstatbuf.st_mode; -#if !USE_UNICODE_WCHAR_CACHE - PyMem_Free(wpath); -#endif /* USE_UNICODE_WCHAR_CACHE */ - return err; -#else - int ret; - PyObject *bytes; - char *cpath; - - bytes = PyUnicode_EncodeFSDefault(path); - if (bytes == NULL) - return -2; - - /* check for embedded null bytes */ - if (PyBytes_AsStringAndSize(bytes, &cpath, NULL) == -1) { - Py_DECREF(bytes); - return -2; - } - - ret = stat(cpath, statbuf); - Py_DECREF(bytes); - return ret; -#endif -} - - -/* This function MUST be kept async-signal-safe on POSIX when raise=0. */ -static int -get_inheritable(int fd, int raise) -{ -#ifdef MS_WINDOWS - HANDLE handle; - DWORD flags; - - handle = _Py_get_osfhandle_noraise(fd); - if (handle == INVALID_HANDLE_VALUE) { - if (raise) - PyErr_SetFromErrno(PyExc_OSError); - return -1; - } - - if (!GetHandleInformation(handle, &flags)) { - if (raise) - PyErr_SetFromWindowsErr(0); - return -1; - } - - return (flags & HANDLE_FLAG_INHERIT); -#else - int flags; - - flags = fcntl(fd, F_GETFD, 0); - if (flags == -1) { - if (raise) - PyErr_SetFromErrno(PyExc_OSError); - return -1; - } - return !(flags & FD_CLOEXEC); -#endif -} - -/* Get the inheritable flag of the specified file descriptor. - Return 1 if the file descriptor can be inherited, 0 if it cannot, - raise an exception and return -1 on error. */ -int -_Py_get_inheritable(int fd) -{ - return get_inheritable(fd, 1); -} - - -/* This function MUST be kept async-signal-safe on POSIX when raise=0. */ -static int -set_inheritable(int fd, int inheritable, int raise, int *atomic_flag_works) -{ -#ifdef MS_WINDOWS - HANDLE handle; - DWORD flags; -#else -#if defined(HAVE_SYS_IOCTL_H) && defined(FIOCLEX) && defined(FIONCLEX) - static int ioctl_works = -1; - int request; - int err; -#endif - int flags, new_flags; - int res; -#endif - - /* atomic_flag_works can only be used to make the file descriptor - non-inheritable */ - assert(!(atomic_flag_works != NULL && inheritable)); - - if (atomic_flag_works != NULL && !inheritable) { - if (*atomic_flag_works == -1) { - int isInheritable = get_inheritable(fd, raise); - if (isInheritable == -1) - return -1; - *atomic_flag_works = !isInheritable; - } - - if (*atomic_flag_works) - return 0; - } - -#ifdef MS_WINDOWS - handle = _Py_get_osfhandle_noraise(fd); - if (handle == INVALID_HANDLE_VALUE) { - if (raise) - PyErr_SetFromErrno(PyExc_OSError); - return -1; - } - - if (inheritable) - flags = HANDLE_FLAG_INHERIT; - else - flags = 0; - - /* This check can be removed once support for Windows 7 ends. */ -#define CONSOLE_PSEUDOHANDLE(handle) (((ULONG_PTR)(handle) & 0x3) == 0x3 && \ - GetFileType(handle) == FILE_TYPE_CHAR) - - if (!CONSOLE_PSEUDOHANDLE(handle) && - !SetHandleInformation(handle, HANDLE_FLAG_INHERIT, flags)) { - if (raise) - PyErr_SetFromWindowsErr(0); - return -1; - } -#undef CONSOLE_PSEUDOHANDLE - return 0; - -#else - -#if defined(HAVE_SYS_IOCTL_H) && defined(FIOCLEX) && defined(FIONCLEX) - if (ioctl_works != 0 && raise != 0) { - /* fast-path: ioctl() only requires one syscall */ - /* caveat: raise=0 is an indicator that we must be async-signal-safe - * thus avoid using ioctl() so we skip the fast-path. */ - if (inheritable) - request = FIONCLEX; - else - request = FIOCLEX; - err = ioctl(fd, request, NULL); - if (!err) { - ioctl_works = 1; - return 0; - } - -#ifdef O_PATH - if (errno == EBADF) { - // bpo-44849: On Linux and FreeBSD, ioctl(FIOCLEX) fails with EBADF - // on O_PATH file descriptors. Fall through to the fcntl() - // implementation. - } - else -#endif - if (errno != ENOTTY && errno != EACCES) { - if (raise) - PyErr_SetFromErrno(PyExc_OSError); - return -1; - } - else { - /* Issue #22258: Here, ENOTTY means "Inappropriate ioctl for - device". The ioctl is declared but not supported by the kernel. - Remember that ioctl() doesn't work. It is the case on - Illumos-based OS for example. - - Issue #27057: When SELinux policy disallows ioctl it will fail - with EACCES. While FIOCLEX is safe operation it may be - unavailable because ioctl was denied altogether. - This can be the case on Android. */ - ioctl_works = 0; - } - /* fallback to fcntl() if ioctl() does not work */ - } -#endif - - /* slow-path: fcntl() requires two syscalls */ - flags = fcntl(fd, F_GETFD); - if (flags < 0) { - if (raise) - PyErr_SetFromErrno(PyExc_OSError); - return -1; - } - - if (inheritable) { - new_flags = flags & ~FD_CLOEXEC; - } - else { - new_flags = flags | FD_CLOEXEC; - } - - if (new_flags == flags) { - /* FD_CLOEXEC flag already set/cleared: nothing to do */ - return 0; - } - - res = fcntl(fd, F_SETFD, new_flags); - if (res < 0) { - if (raise) - PyErr_SetFromErrno(PyExc_OSError); - return -1; - } - return 0; -#endif -} - -/* Make the file descriptor non-inheritable. - Return 0 on success, set errno and return -1 on error. */ -static int -make_non_inheritable(int fd) -{ - return set_inheritable(fd, 0, 0, NULL); -} - -/* Set the inheritable flag of the specified file descriptor. - On success: return 0, on error: raise an exception and return -1. - - If atomic_flag_works is not NULL: - - * if *atomic_flag_works==-1, check if the inheritable is set on the file - descriptor: if yes, set *atomic_flag_works to 1, otherwise set to 0 and - set the inheritable flag - * if *atomic_flag_works==1: do nothing - * if *atomic_flag_works==0: set inheritable flag to False - - Set atomic_flag_works to NULL if no atomic flag was used to create the - file descriptor. - - atomic_flag_works can only be used to make a file descriptor - non-inheritable: atomic_flag_works must be NULL if inheritable=1. */ -int -_Py_set_inheritable(int fd, int inheritable, int *atomic_flag_works) -{ - return set_inheritable(fd, inheritable, 1, atomic_flag_works); -} - -/* Same as _Py_set_inheritable() but on error, set errno and - don't raise an exception. - This function is async-signal-safe. */ -int -_Py_set_inheritable_async_safe(int fd, int inheritable, int *atomic_flag_works) -{ - return set_inheritable(fd, inheritable, 0, atomic_flag_works); -} - -static int -_Py_open_impl(const char *pathname, int flags, int gil_held) -{ - int fd; - int async_err = 0; -#ifndef MS_WINDOWS - int *atomic_flag_works; -#endif - -#ifdef MS_WINDOWS - flags |= O_NOINHERIT; -#elif defined(O_CLOEXEC) - atomic_flag_works = &_Py_open_cloexec_works; - flags |= O_CLOEXEC; -#else - atomic_flag_works = NULL; -#endif - - if (gil_held) { - PyObject *pathname_obj = PyUnicode_DecodeFSDefault(pathname); - if (pathname_obj == NULL) { - return -1; - } - if (PySys_Audit("open", "OOi", pathname_obj, Py_None, flags) < 0) { - Py_DECREF(pathname_obj); - return -1; - } - - do { - Py_BEGIN_ALLOW_THREADS - fd = open(pathname, flags); - Py_END_ALLOW_THREADS - } while (fd < 0 - && errno == EINTR && !(async_err = PyErr_CheckSignals())); - if (async_err) { - Py_DECREF(pathname_obj); - return -1; - } - if (fd < 0) { - PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError, pathname_obj, NULL); - Py_DECREF(pathname_obj); - return -1; - } - Py_DECREF(pathname_obj); - } - else { - fd = open(pathname, flags); - if (fd < 0) - return -1; - } - -#ifndef MS_WINDOWS - if (set_inheritable(fd, 0, gil_held, atomic_flag_works) < 0) { - close(fd); - return -1; - } -#endif - - return fd; -} - -/* Open a file with the specified flags (wrapper to open() function). - Return a file descriptor on success. Raise an exception and return -1 on - error. - - The file descriptor is created non-inheritable. - - When interrupted by a signal (open() fails with EINTR), retry the syscall, - except if the Python signal handler raises an exception. - - Release the GIL to call open(). The caller must hold the GIL. */ -int -_Py_open(const char *pathname, int flags) -{ - /* _Py_open() must be called with the GIL held. */ - assert(PyGILState_Check()); - return _Py_open_impl(pathname, flags, 1); -} - -/* Open a file with the specified flags (wrapper to open() function). - Return a file descriptor on success. Set errno and return -1 on error. - - The file descriptor is created non-inheritable. - - If interrupted by a signal, fail with EINTR. */ -int -_Py_open_noraise(const char *pathname, int flags) -{ - return _Py_open_impl(pathname, flags, 0); -} - -/* Open a file. Use _wfopen() on Windows, encode the path to the locale - encoding and use fopen() otherwise. - - The file descriptor is created non-inheritable. - - If interrupted by a signal, fail with EINTR. */ -FILE * -_Py_wfopen(const wchar_t *path, const wchar_t *mode) -{ - FILE *f; - if (PySys_Audit("open", "uui", path, mode, 0) < 0) { - return NULL; - } -#ifndef MS_WINDOWS - char *cpath; - char cmode[10]; - size_t r; - r = wcstombs(cmode, mode, 10); - if (r == DECODE_ERROR || r >= 10) { - errno = EINVAL; - return NULL; - } - cpath = _Py_EncodeLocaleRaw(path, NULL); - if (cpath == NULL) { - return NULL; - } - f = fopen(cpath, cmode); - PyMem_RawFree(cpath); -#else - f = _wfopen(path, mode); -#endif - if (f == NULL) - return NULL; - if (make_non_inheritable(fileno(f)) < 0) { - fclose(f); - return NULL; - } - return f; -} - - -/* Open a file. Call _wfopen() on Windows, or encode the path to the filesystem - encoding and call fopen() otherwise. - - Return the new file object on success. Raise an exception and return NULL - on error. - - The file descriptor is created non-inheritable. - - When interrupted by a signal (open() fails with EINTR), retry the syscall, - except if the Python signal handler raises an exception. - - Release the GIL to call _wfopen() or fopen(). The caller must hold - the GIL. */ -FILE* -_Py_fopen_obj(PyObject *path, const char *mode) -{ - FILE *f; - int async_err = 0; -#ifdef MS_WINDOWS - wchar_t wmode[10]; - int usize; - - assert(PyGILState_Check()); - - if (PySys_Audit("open", "Osi", path, mode, 0) < 0) { - return NULL; - } - if (!PyUnicode_Check(path)) { - PyErr_Format(PyExc_TypeError, - "str file path expected under Windows, got %R", - Py_TYPE(path)); - return NULL; - } -#if USE_UNICODE_WCHAR_CACHE - const wchar_t *wpath = _PyUnicode_AsUnicode(path); -#else /* USE_UNICODE_WCHAR_CACHE */ - wchar_t *wpath = PyUnicode_AsWideCharString(path, NULL); -#endif /* USE_UNICODE_WCHAR_CACHE */ - if (wpath == NULL) - return NULL; - - usize = MultiByteToWideChar(CP_ACP, 0, mode, -1, - wmode, Py_ARRAY_LENGTH(wmode)); - if (usize == 0) { - PyErr_SetFromWindowsErr(0); -#if !USE_UNICODE_WCHAR_CACHE - PyMem_Free(wpath); -#endif /* USE_UNICODE_WCHAR_CACHE */ - return NULL; - } - - do { - Py_BEGIN_ALLOW_THREADS - f = _wfopen(wpath, wmode); - Py_END_ALLOW_THREADS - } while (f == NULL - && errno == EINTR && !(async_err = PyErr_CheckSignals())); -#if !USE_UNICODE_WCHAR_CACHE - PyMem_Free(wpath); -#endif /* USE_UNICODE_WCHAR_CACHE */ -#else - PyObject *bytes; - const char *path_bytes; - - assert(PyGILState_Check()); - - if (!PyUnicode_FSConverter(path, &bytes)) - return NULL; - path_bytes = PyBytes_AS_STRING(bytes); - - if (PySys_Audit("open", "Osi", path, mode, 0) < 0) { - Py_DECREF(bytes); - return NULL; - } - - do { - Py_BEGIN_ALLOW_THREADS - f = fopen(path_bytes, mode); - Py_END_ALLOW_THREADS - } while (f == NULL - && errno == EINTR && !(async_err = PyErr_CheckSignals())); - - Py_DECREF(bytes); -#endif - if (async_err) - return NULL; - - if (f == NULL) { - PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path); - return NULL; - } - - if (set_inheritable(fileno(f), 0, 1, NULL) < 0) { - fclose(f); - return NULL; - } - return f; -} - -/* Read count bytes from fd into buf. - - On success, return the number of read bytes, it can be lower than count. - If the current file offset is at or past the end of file, no bytes are read, - and read() returns zero. - - On error, raise an exception, set errno and return -1. - - When interrupted by a signal (read() fails with EINTR), retry the syscall. - If the Python signal handler raises an exception, the function returns -1 - (the syscall is not retried). - - Release the GIL to call read(). The caller must hold the GIL. */ -Py_ssize_t -_Py_read(int fd, void *buf, size_t count) -{ - Py_ssize_t n; - int err; - int async_err = 0; - - assert(PyGILState_Check()); - - /* _Py_read() must not be called with an exception set, otherwise the - * caller may think that read() was interrupted by a signal and the signal - * handler raised an exception. */ - assert(!PyErr_Occurred()); - - if (count > _PY_READ_MAX) { - count = _PY_READ_MAX; - } - - _Py_BEGIN_SUPPRESS_IPH - do { - Py_BEGIN_ALLOW_THREADS - errno = 0; -#ifdef MS_WINDOWS - n = read(fd, buf, (int)count); -#else - n = read(fd, buf, count); -#endif - /* save/restore errno because PyErr_CheckSignals() - * and PyErr_SetFromErrno() can modify it */ - err = errno; - Py_END_ALLOW_THREADS - } while (n < 0 && err == EINTR && - !(async_err = PyErr_CheckSignals())); - _Py_END_SUPPRESS_IPH - - if (async_err) { - /* read() was interrupted by a signal (failed with EINTR) - * and the Python signal handler raised an exception */ - errno = err; - assert(errno == EINTR && PyErr_Occurred()); - return -1; - } - if (n < 0) { - PyErr_SetFromErrno(PyExc_OSError); - errno = err; - return -1; - } - - return n; -} - -static Py_ssize_t -_Py_write_impl(int fd, const void *buf, size_t count, int gil_held) -{ - Py_ssize_t n; - int err; - int async_err = 0; - - _Py_BEGIN_SUPPRESS_IPH -#ifdef MS_WINDOWS - if (count > 32767) { - /* Issue #11395: the Windows console returns an error (12: not - enough space error) on writing into stdout if stdout mode is - binary and the length is greater than 66,000 bytes (or less, - depending on heap usage). */ - if (gil_held) { - Py_BEGIN_ALLOW_THREADS - if (isatty(fd)) { - count = 32767; - } - Py_END_ALLOW_THREADS - } else { - if (isatty(fd)) { - count = 32767; - } - } - } -#endif - if (count > _PY_WRITE_MAX) { - count = _PY_WRITE_MAX; - } - - if (gil_held) { - do { - Py_BEGIN_ALLOW_THREADS - errno = 0; -#ifdef MS_WINDOWS - n = write(fd, buf, (int)count); -#else - n = write(fd, buf, count); -#endif - /* save/restore errno because PyErr_CheckSignals() - * and PyErr_SetFromErrno() can modify it */ - err = errno; - Py_END_ALLOW_THREADS - } while (n < 0 && err == EINTR && - !(async_err = PyErr_CheckSignals())); - } - else { - do { - errno = 0; -#ifdef MS_WINDOWS - n = write(fd, buf, (int)count); -#else - n = write(fd, buf, count); -#endif - err = errno; - } while (n < 0 && err == EINTR); - } - _Py_END_SUPPRESS_IPH - - if (async_err) { - /* write() was interrupted by a signal (failed with EINTR) - and the Python signal handler raised an exception (if gil_held is - nonzero). */ - errno = err; - assert(errno == EINTR && (!gil_held || PyErr_Occurred())); - return -1; - } - if (n < 0) { - if (gil_held) - PyErr_SetFromErrno(PyExc_OSError); - errno = err; - return -1; - } - - return n; -} - -/* Write count bytes of buf into fd. - - On success, return the number of written bytes, it can be lower than count - including 0. On error, raise an exception, set errno and return -1. - - When interrupted by a signal (write() fails with EINTR), retry the syscall. - If the Python signal handler raises an exception, the function returns -1 - (the syscall is not retried). - - Release the GIL to call write(). The caller must hold the GIL. */ -Py_ssize_t -_Py_write(int fd, const void *buf, size_t count) -{ - assert(PyGILState_Check()); - - /* _Py_write() must not be called with an exception set, otherwise the - * caller may think that write() was interrupted by a signal and the signal - * handler raised an exception. */ - assert(!PyErr_Occurred()); - - return _Py_write_impl(fd, buf, count, 1); -} - -/* Write count bytes of buf into fd. - * - * On success, return the number of written bytes, it can be lower than count - * including 0. On error, set errno and return -1. - * - * When interrupted by a signal (write() fails with EINTR), retry the syscall - * without calling the Python signal handler. */ -Py_ssize_t -_Py_write_noraise(int fd, const void *buf, size_t count) -{ - return _Py_write_impl(fd, buf, count, 0); -} - -#ifdef HAVE_READLINK - -/* Read value of symbolic link. Encode the path to the locale encoding, decode - the result from the locale encoding. - - Return -1 on encoding error, on readlink() error, if the internal buffer is - too short, on decoding error, or if 'buf' is too short. */ -int -_Py_wreadlink(const wchar_t *path, wchar_t *buf, size_t buflen) -{ - char *cpath; - char cbuf[MAXPATHLEN]; - size_t cbuf_len = Py_ARRAY_LENGTH(cbuf); - wchar_t *wbuf; - Py_ssize_t res; - size_t r1; - - cpath = _Py_EncodeLocaleRaw(path, NULL); - if (cpath == NULL) { - errno = EINVAL; - return -1; - } - res = readlink(cpath, cbuf, cbuf_len); - PyMem_RawFree(cpath); - if (res == -1) { - return -1; - } - if ((size_t)res == cbuf_len) { - errno = EINVAL; - return -1; - } - cbuf[res] = '\0'; /* buf will be null terminated */ - wbuf = Py_DecodeLocale(cbuf, &r1); - if (wbuf == NULL) { - errno = EINVAL; - return -1; - } - /* wbuf must have space to store the trailing NUL character */ - if (buflen <= r1) { - PyMem_RawFree(wbuf); - errno = EINVAL; - return -1; - } - wcsncpy(buf, wbuf, buflen); - PyMem_RawFree(wbuf); - return (int)r1; -} -#endif - -#ifdef HAVE_REALPATH - -/* Return the canonicalized absolute pathname. Encode path to the locale - encoding, decode the result from the locale encoding. - - Return NULL on encoding error, realpath() error, decoding error - or if 'resolved_path' is too short. */ -wchar_t* -_Py_wrealpath(const wchar_t *path, - wchar_t *resolved_path, size_t resolved_path_len) -{ - char *cpath; - char cresolved_path[MAXPATHLEN]; - wchar_t *wresolved_path; - char *res; - size_t r; - cpath = _Py_EncodeLocaleRaw(path, NULL); - if (cpath == NULL) { - errno = EINVAL; - return NULL; - } - res = realpath(cpath, cresolved_path); - PyMem_RawFree(cpath); - if (res == NULL) - return NULL; - - wresolved_path = Py_DecodeLocale(cresolved_path, &r); - if (wresolved_path == NULL) { - errno = EINVAL; - return NULL; - } - /* wresolved_path must have space to store the trailing NUL character */ - if (resolved_path_len <= r) { - PyMem_RawFree(wresolved_path); - errno = EINVAL; - return NULL; - } - wcsncpy(resolved_path, wresolved_path, resolved_path_len); - PyMem_RawFree(wresolved_path); - return resolved_path; -} -#endif - - -#ifndef MS_WINDOWS -int -_Py_isabs(const wchar_t *path) -{ - return (path[0] == SEP); -} -#endif - - -/* Get an absolute path. - On error (ex: fail to get the current directory), return -1. - On memory allocation failure, set *abspath_p to NULL and return 0. - On success, return a newly allocated to *abspath_p to and return 0. - The string must be freed by PyMem_RawFree(). */ -int -_Py_abspath(const wchar_t *path, wchar_t **abspath_p) -{ -#ifdef MS_WINDOWS - wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf; - DWORD result; - - result = GetFullPathNameW(path, - Py_ARRAY_LENGTH(woutbuf), woutbuf, - NULL); - if (!result) { - return -1; - } - - if (result > Py_ARRAY_LENGTH(woutbuf)) { - if ((size_t)result <= (size_t)PY_SSIZE_T_MAX / sizeof(wchar_t)) { - woutbufp = PyMem_RawMalloc((size_t)result * sizeof(wchar_t)); - } - else { - woutbufp = NULL; - } - if (!woutbufp) { - *abspath_p = NULL; - return 0; - } - - result = GetFullPathNameW(path, result, woutbufp, NULL); - if (!result) { - PyMem_RawFree(woutbufp); - return -1; - } - } - - if (woutbufp != woutbuf) { - *abspath_p = woutbufp; - return 0; - } - - *abspath_p = _PyMem_RawWcsdup(woutbufp); - return 0; -#else - if (_Py_isabs(path)) { - *abspath_p = _PyMem_RawWcsdup(path); - return 0; - } - - wchar_t cwd[MAXPATHLEN + 1]; - cwd[Py_ARRAY_LENGTH(cwd) - 1] = 0; - if (!_Py_wgetcwd(cwd, Py_ARRAY_LENGTH(cwd) - 1)) { - /* unable to get the current directory */ - return -1; - } - - size_t cwd_len = wcslen(cwd); - size_t path_len = wcslen(path); - size_t len = cwd_len + 1 + path_len + 1; - if (len <= (size_t)PY_SSIZE_T_MAX / sizeof(wchar_t)) { - *abspath_p = PyMem_RawMalloc(len * sizeof(wchar_t)); - } - else { - *abspath_p = NULL; - } - if (*abspath_p == NULL) { - return 0; - } - - wchar_t *abspath = *abspath_p; - memcpy(abspath, cwd, cwd_len * sizeof(wchar_t)); - abspath += cwd_len; - - *abspath = (wchar_t)SEP; - abspath++; - - memcpy(abspath, path, path_len * sizeof(wchar_t)); - abspath += path_len; - - *abspath = 0; - return 0; -#endif -} - - -/* Get the current directory. buflen is the buffer size in wide characters - including the null character. Decode the path from the locale encoding. - - Return NULL on getcwd() error, on decoding error, or if 'buf' is - too short. */ -wchar_t* -_Py_wgetcwd(wchar_t *buf, size_t buflen) -{ -#ifdef MS_WINDOWS - int ibuflen = (int)Py_MIN(buflen, INT_MAX); - return _wgetcwd(buf, ibuflen); -#else - char fname[MAXPATHLEN]; - wchar_t *wname; - size_t len; - - if (getcwd(fname, Py_ARRAY_LENGTH(fname)) == NULL) - return NULL; - wname = Py_DecodeLocale(fname, &len); - if (wname == NULL) - return NULL; - /* wname must have space to store the trailing NUL character */ - if (buflen <= len) { - PyMem_RawFree(wname); - return NULL; - } - wcsncpy(buf, wname, buflen); - PyMem_RawFree(wname); - return buf; -#endif -} - -/* Duplicate a file descriptor. The new file descriptor is created as - non-inheritable. Return a new file descriptor on success, raise an OSError - exception and return -1 on error. - - The GIL is released to call dup(). The caller must hold the GIL. */ -int -_Py_dup(int fd) -{ -#ifdef MS_WINDOWS - HANDLE handle; -#endif - - assert(PyGILState_Check()); - -#ifdef MS_WINDOWS - handle = _Py_get_osfhandle(fd); - if (handle == INVALID_HANDLE_VALUE) - return -1; - - Py_BEGIN_ALLOW_THREADS - _Py_BEGIN_SUPPRESS_IPH - fd = dup(fd); - _Py_END_SUPPRESS_IPH - Py_END_ALLOW_THREADS - if (fd < 0) { - PyErr_SetFromErrno(PyExc_OSError); - return -1; - } - - if (_Py_set_inheritable(fd, 0, NULL) < 0) { - _Py_BEGIN_SUPPRESS_IPH - close(fd); - _Py_END_SUPPRESS_IPH - return -1; - } -#elif defined(HAVE_FCNTL_H) && defined(F_DUPFD_CLOEXEC) - Py_BEGIN_ALLOW_THREADS - _Py_BEGIN_SUPPRESS_IPH - fd = fcntl(fd, F_DUPFD_CLOEXEC, 0); - _Py_END_SUPPRESS_IPH - Py_END_ALLOW_THREADS - if (fd < 0) { - PyErr_SetFromErrno(PyExc_OSError); - return -1; - } - -#else - Py_BEGIN_ALLOW_THREADS - _Py_BEGIN_SUPPRESS_IPH - fd = dup(fd); - _Py_END_SUPPRESS_IPH - Py_END_ALLOW_THREADS - if (fd < 0) { - PyErr_SetFromErrno(PyExc_OSError); - return -1; - } - - if (_Py_set_inheritable(fd, 0, NULL) < 0) { - _Py_BEGIN_SUPPRESS_IPH - close(fd); - _Py_END_SUPPRESS_IPH - return -1; - } -#endif - return fd; -} - -#ifndef MS_WINDOWS -/* Get the blocking mode of the file descriptor. - Return 0 if the O_NONBLOCK flag is set, 1 if the flag is cleared, - raise an exception and return -1 on error. */ -int -_Py_get_blocking(int fd) -{ - int flags; - _Py_BEGIN_SUPPRESS_IPH - flags = fcntl(fd, F_GETFL, 0); - _Py_END_SUPPRESS_IPH - if (flags < 0) { - PyErr_SetFromErrno(PyExc_OSError); - return -1; - } - - return !(flags & O_NONBLOCK); -} - -/* Set the blocking mode of the specified file descriptor. - - Set the O_NONBLOCK flag if blocking is False, clear the O_NONBLOCK flag - otherwise. - - Return 0 on success, raise an exception and return -1 on error. */ -int -_Py_set_blocking(int fd, int blocking) -{ -/* bpo-41462: On VxWorks, ioctl(FIONBIO) only works on sockets. - Use fcntl() instead. */ -#if defined(HAVE_SYS_IOCTL_H) && defined(FIONBIO) && !defined(__VXWORKS__) - int arg = !blocking; - if (ioctl(fd, FIONBIO, &arg) < 0) - goto error; -#else - int flags, res; - - _Py_BEGIN_SUPPRESS_IPH - flags = fcntl(fd, F_GETFL, 0); - if (flags >= 0) { - if (blocking) - flags = flags & (~O_NONBLOCK); - else - flags = flags | O_NONBLOCK; - - res = fcntl(fd, F_SETFL, flags); - } else { - res = -1; - } - _Py_END_SUPPRESS_IPH - - if (res < 0) - goto error; -#endif - return 0; - -error: - PyErr_SetFromErrno(PyExc_OSError); - return -1; -} -#else /* MS_WINDOWS */ -void* -_Py_get_osfhandle_noraise(int fd) -{ - void *handle; - _Py_BEGIN_SUPPRESS_IPH - handle = (void*)_get_osfhandle(fd); - _Py_END_SUPPRESS_IPH - return handle; -} - -void* -_Py_get_osfhandle(int fd) -{ - void *handle = _Py_get_osfhandle_noraise(fd); - if (handle == INVALID_HANDLE_VALUE) - PyErr_SetFromErrno(PyExc_OSError); - - return handle; -} - -int -_Py_open_osfhandle_noraise(void *handle, int flags) -{ - int fd; - _Py_BEGIN_SUPPRESS_IPH - fd = _open_osfhandle((intptr_t)handle, flags); - _Py_END_SUPPRESS_IPH - return fd; -} - -int -_Py_open_osfhandle(void *handle, int flags) -{ - int fd = _Py_open_osfhandle_noraise(handle, flags); - if (fd == -1) - PyErr_SetFromErrno(PyExc_OSError); - - return fd; -} -#endif /* MS_WINDOWS */ - -int -_Py_GetLocaleconvNumeric(struct lconv *lc, - PyObject **decimal_point, PyObject **thousands_sep) -{ - assert(decimal_point != NULL); - assert(thousands_sep != NULL); - -#ifndef MS_WINDOWS - int change_locale = 0; - if ((strlen(lc->decimal_point) > 1 || ((unsigned char)lc->decimal_point[0]) > 127)) { - change_locale = 1; - } - if ((strlen(lc->thousands_sep) > 1 || ((unsigned char)lc->thousands_sep[0]) > 127)) { - change_locale = 1; - } - - /* Keep a copy of the LC_CTYPE locale */ - char *oldloc = NULL, *loc = NULL; - if (change_locale) { - oldloc = setlocale(LC_CTYPE, NULL); - if (!oldloc) { - PyErr_SetString(PyExc_RuntimeWarning, - "failed to get LC_CTYPE locale"); - return -1; - } - - oldloc = _PyMem_Strdup(oldloc); - if (!oldloc) { - PyErr_NoMemory(); - return -1; - } - - loc = setlocale(LC_NUMERIC, NULL); - if (loc != NULL && strcmp(loc, oldloc) == 0) { - loc = NULL; - } - - if (loc != NULL) { - /* Only set the locale temporarily the LC_CTYPE locale - if LC_NUMERIC locale is different than LC_CTYPE locale and - decimal_point and/or thousands_sep are non-ASCII or longer than - 1 byte */ - setlocale(LC_CTYPE, loc); - } - } - -#define GET_LOCALE_STRING(ATTR) PyUnicode_DecodeLocale(lc->ATTR, NULL) -#else /* MS_WINDOWS */ -/* Use _W_* fields of Windows strcut lconv */ -#define GET_LOCALE_STRING(ATTR) PyUnicode_FromWideChar(lc->_W_ ## ATTR, -1) -#endif /* MS_WINDOWS */ - - int res = -1; - - *decimal_point = GET_LOCALE_STRING(decimal_point); - if (*decimal_point == NULL) { - goto done; - } - - *thousands_sep = GET_LOCALE_STRING(thousands_sep); - if (*thousands_sep == NULL) { - goto done; - } - - res = 0; - -done: -#ifndef MS_WINDOWS - if (loc != NULL) { - setlocale(LC_CTYPE, oldloc); - } - PyMem_Free(oldloc); -#endif - return res; - -#undef GET_LOCALE_STRING -} - -/* Our selection logic for which function to use is as follows: - * 1. If close_range(2) is available, always prefer that; it's better for - * contiguous ranges like this than fdwalk(3) which entails iterating over - * the entire fd space and simply doing nothing for those outside the range. - * 2. If closefrom(2) is available, we'll attempt to use that next if we're - * closing up to sysconf(_SC_OPEN_MAX). - * 2a. Fallback to fdwalk(3) if we're not closing up to sysconf(_SC_OPEN_MAX), - * as that will be more performant if the range happens to have any chunk of - * non-opened fd in the middle. - * 2b. If fdwalk(3) isn't available, just do a plain close(2) loop. - */ -#ifdef __FreeBSD__ -# define USE_CLOSEFROM -#endif /* __FreeBSD__ */ - -#ifdef HAVE_FDWALK -# define USE_FDWALK -#endif /* HAVE_FDWALK */ - -#ifdef USE_FDWALK -static int -_fdwalk_close_func(void *lohi, int fd) -{ - int lo = ((int *)lohi)[0]; - int hi = ((int *)lohi)[1]; - - if (fd >= hi) { - return 1; - } - else if (fd >= lo) { - /* Ignore errors */ - (void)close(fd); - } - return 0; -} -#endif /* USE_FDWALK */ - -/* Closes all file descriptors in [first, last], ignoring errors. */ -void -_Py_closerange(int first, int last) -{ - first = Py_MAX(first, 0); - _Py_BEGIN_SUPPRESS_IPH -#ifdef HAVE_CLOSE_RANGE - if (close_range(first, last, 0) == 0) { - /* close_range() ignores errors when it closes file descriptors. - * Possible reasons of an error return are lack of kernel support - * or denial of the underlying syscall by a seccomp sandbox on Linux. - * Fallback to other methods in case of any error. */ - } - else -#endif /* HAVE_CLOSE_RANGE */ -#ifdef USE_CLOSEFROM - if (last >= sysconf(_SC_OPEN_MAX)) { - /* Any errors encountered while closing file descriptors are ignored */ - closefrom(first); - } - else -#endif /* USE_CLOSEFROM */ -#ifdef USE_FDWALK - { - int lohi[2]; - lohi[0] = first; - lohi[1] = last + 1; - fdwalk(_fdwalk_close_func, lohi); - } -#else - { - for (int i = first; i <= last; i++) { - /* Ignore errors */ - (void)close(i); - } - } -#endif /* USE_FDWALK */ - _Py_END_SUPPRESS_IPH -} diff --git a/contrib/tools/python3/src/Python/formatter_unicode.c b/contrib/tools/python3/src/Python/formatter_unicode.c deleted file mode 100644 index 7b5a7bd04eb..00000000000 --- a/contrib/tools/python3/src/Python/formatter_unicode.c +++ /dev/null @@ -1,1600 +0,0 @@ -/* implements the unicode (as opposed to string) version of the - built-in formatters for string, int, float. that is, the versions - of int.__float__, etc., that take and return unicode objects */ - -#include "Python.h" -#include "pycore_fileutils.h" -#include <locale.h> - -/* Raises an exception about an unknown presentation type for this - * type. */ - -static void -unknown_presentation_type(Py_UCS4 presentation_type, - const char* type_name) -{ - /* %c might be out-of-range, hence the two cases. */ - if (presentation_type > 32 && presentation_type < 128) - PyErr_Format(PyExc_ValueError, - "Unknown format code '%c' " - "for object of type '%.200s'", - (char)presentation_type, - type_name); - else - PyErr_Format(PyExc_ValueError, - "Unknown format code '\\x%x' " - "for object of type '%.200s'", - (unsigned int)presentation_type, - type_name); -} - -static void -invalid_thousands_separator_type(char specifier, Py_UCS4 presentation_type) -{ - assert(specifier == ',' || specifier == '_'); - if (presentation_type > 32 && presentation_type < 128) - PyErr_Format(PyExc_ValueError, - "Cannot specify '%c' with '%c'.", - specifier, (char)presentation_type); - else - PyErr_Format(PyExc_ValueError, - "Cannot specify '%c' with '\\x%x'.", - specifier, (unsigned int)presentation_type); -} - -static void -invalid_comma_and_underscore(void) -{ - PyErr_Format(PyExc_ValueError, "Cannot specify both ',' and '_'."); -} - -/* - get_integer consumes 0 or more decimal digit characters from an - input string, updates *result with the corresponding positive - integer, and returns the number of digits consumed. - - returns -1 on error. -*/ -static int -get_integer(PyObject *str, Py_ssize_t *ppos, Py_ssize_t end, - Py_ssize_t *result) -{ - Py_ssize_t accumulator, digitval, pos = *ppos; - int numdigits; - int kind = PyUnicode_KIND(str); - const void *data = PyUnicode_DATA(str); - - accumulator = numdigits = 0; - for (; pos < end; pos++, numdigits++) { - digitval = Py_UNICODE_TODECIMAL(PyUnicode_READ(kind, data, pos)); - if (digitval < 0) - break; - /* - Detect possible overflow before it happens: - - accumulator * 10 + digitval > PY_SSIZE_T_MAX if and only if - accumulator > (PY_SSIZE_T_MAX - digitval) / 10. - */ - if (accumulator > (PY_SSIZE_T_MAX - digitval) / 10) { - PyErr_Format(PyExc_ValueError, - "Too many decimal digits in format string"); - *ppos = pos; - return -1; - } - accumulator = accumulator * 10 + digitval; - } - *ppos = pos; - *result = accumulator; - return numdigits; -} - -/************************************************************************/ -/*********** standard format specifier parsing **************************/ -/************************************************************************/ - -/* returns true if this character is a specifier alignment token */ -Py_LOCAL_INLINE(int) -is_alignment_token(Py_UCS4 c) -{ - switch (c) { - case '<': case '>': case '=': case '^': - return 1; - default: - return 0; - } -} - -/* returns true if this character is a sign element */ -Py_LOCAL_INLINE(int) -is_sign_element(Py_UCS4 c) -{ - switch (c) { - case ' ': case '+': case '-': - return 1; - default: - return 0; - } -} - -/* Locale type codes. LT_NO_LOCALE must be zero. */ -enum LocaleType { - LT_NO_LOCALE = 0, - LT_DEFAULT_LOCALE = ',', - LT_UNDERSCORE_LOCALE = '_', - LT_UNDER_FOUR_LOCALE, - LT_CURRENT_LOCALE -}; - -typedef struct { - Py_UCS4 fill_char; - Py_UCS4 align; - int alternate; - Py_UCS4 sign; - Py_ssize_t width; - enum LocaleType thousands_separators; - Py_ssize_t precision; - Py_UCS4 type; -} InternalFormatSpec; - -#if 0 -/* Occasionally useful for debugging. Should normally be commented out. */ -static void -DEBUG_PRINT_FORMAT_SPEC(InternalFormatSpec *format) -{ - printf("internal format spec: fill_char %d\n", format->fill_char); - printf("internal format spec: align %d\n", format->align); - printf("internal format spec: alternate %d\n", format->alternate); - printf("internal format spec: sign %d\n", format->sign); - printf("internal format spec: width %zd\n", format->width); - printf("internal format spec: thousands_separators %d\n", - format->thousands_separators); - printf("internal format spec: precision %zd\n", format->precision); - printf("internal format spec: type %c\n", format->type); - printf("\n"); -} -#endif - - -/* - ptr points to the start of the format_spec, end points just past its end. - fills in format with the parsed information. - returns 1 on success, 0 on failure. - if failure, sets the exception -*/ -static int -parse_internal_render_format_spec(PyObject *format_spec, - Py_ssize_t start, Py_ssize_t end, - InternalFormatSpec *format, - char default_type, - char default_align) -{ - Py_ssize_t pos = start; - int kind = PyUnicode_KIND(format_spec); - const void *data = PyUnicode_DATA(format_spec); - /* end-pos is used throughout this code to specify the length of - the input string */ -#define READ_spec(index) PyUnicode_READ(kind, data, index) - - Py_ssize_t consumed; - int align_specified = 0; - int fill_char_specified = 0; - - format->fill_char = ' '; - format->align = default_align; - format->alternate = 0; - format->sign = '\0'; - format->width = -1; - format->thousands_separators = LT_NO_LOCALE; - format->precision = -1; - format->type = default_type; - - /* If the second char is an alignment token, - then parse the fill char */ - if (end-pos >= 2 && is_alignment_token(READ_spec(pos+1))) { - format->align = READ_spec(pos+1); - format->fill_char = READ_spec(pos); - fill_char_specified = 1; - align_specified = 1; - pos += 2; - } - else if (end-pos >= 1 && is_alignment_token(READ_spec(pos))) { - format->align = READ_spec(pos); - align_specified = 1; - ++pos; - } - - /* Parse the various sign options */ - if (end-pos >= 1 && is_sign_element(READ_spec(pos))) { - format->sign = READ_spec(pos); - ++pos; - } - - /* If the next character is #, we're in alternate mode. This only - applies to integers. */ - if (end-pos >= 1 && READ_spec(pos) == '#') { - format->alternate = 1; - ++pos; - } - - /* The special case for 0-padding (backwards compat) */ - if (!fill_char_specified && end-pos >= 1 && READ_spec(pos) == '0') { - format->fill_char = '0'; - if (!align_specified && default_align == '>') { - format->align = '='; - } - ++pos; - } - - consumed = get_integer(format_spec, &pos, end, &format->width); - if (consumed == -1) - /* Overflow error. Exception already set. */ - return 0; - - /* If consumed is 0, we didn't consume any characters for the - width. In that case, reset the width to -1, because - get_integer() will have set it to zero. -1 is how we record - that the width wasn't specified. */ - if (consumed == 0) - format->width = -1; - - /* Comma signifies add thousands separators */ - if (end-pos && READ_spec(pos) == ',') { - format->thousands_separators = LT_DEFAULT_LOCALE; - ++pos; - } - /* Underscore signifies add thousands separators */ - if (end-pos && READ_spec(pos) == '_') { - if (format->thousands_separators != LT_NO_LOCALE) { - invalid_comma_and_underscore(); - return 0; - } - format->thousands_separators = LT_UNDERSCORE_LOCALE; - ++pos; - } - if (end-pos && READ_spec(pos) == ',') { - if (format->thousands_separators == LT_UNDERSCORE_LOCALE) { - invalid_comma_and_underscore(); - return 0; - } - } - - /* Parse field precision */ - if (end-pos && READ_spec(pos) == '.') { - ++pos; - - consumed = get_integer(format_spec, &pos, end, &format->precision); - if (consumed == -1) - /* Overflow error. Exception already set. */ - return 0; - - /* Not having a precision after a dot is an error. */ - if (consumed == 0) { - PyErr_Format(PyExc_ValueError, - "Format specifier missing precision"); - return 0; - } - - } - - /* Finally, parse the type field. */ - - if (end-pos > 1) { - /* More than one char remain, invalid format specifier. */ - PyErr_Format(PyExc_ValueError, "Invalid format specifier"); - return 0; - } - - if (end-pos == 1) { - format->type = READ_spec(pos); - ++pos; - } - - /* Do as much validating as we can, just by looking at the format - specifier. Do not take into account what type of formatting - we're doing (int, float, string). */ - - if (format->thousands_separators) { - switch (format->type) { - case 'd': - case 'e': - case 'f': - case 'g': - case 'E': - case 'G': - case '%': - case 'F': - case '\0': - /* These are allowed. See PEP 378.*/ - break; - case 'b': - case 'o': - case 'x': - case 'X': - /* Underscores are allowed in bin/oct/hex. See PEP 515. */ - if (format->thousands_separators == LT_UNDERSCORE_LOCALE) { - /* Every four digits, not every three, in bin/oct/hex. */ - format->thousands_separators = LT_UNDER_FOUR_LOCALE; - break; - } - /* fall through */ - default: - invalid_thousands_separator_type(format->thousands_separators, format->type); - return 0; - } - } - - assert (format->align <= 127); - assert (format->sign <= 127); - return 1; -} - -/* Calculate the padding needed. */ -static void -calc_padding(Py_ssize_t nchars, Py_ssize_t width, Py_UCS4 align, - Py_ssize_t *n_lpadding, Py_ssize_t *n_rpadding, - Py_ssize_t *n_total) -{ - if (width >= 0) { - if (nchars > width) - *n_total = nchars; - else - *n_total = width; - } - else { - /* not specified, use all of the chars and no more */ - *n_total = nchars; - } - - /* Figure out how much leading space we need, based on the - aligning */ - if (align == '>') - *n_lpadding = *n_total - nchars; - else if (align == '^') - *n_lpadding = (*n_total - nchars) / 2; - else if (align == '<' || align == '=') - *n_lpadding = 0; - else { - /* We should never have an unspecified alignment. */ - Py_UNREACHABLE(); - } - - *n_rpadding = *n_total - nchars - *n_lpadding; -} - -/* Do the padding, and return a pointer to where the caller-supplied - content goes. */ -static int -fill_padding(_PyUnicodeWriter *writer, - Py_ssize_t nchars, - Py_UCS4 fill_char, Py_ssize_t n_lpadding, - Py_ssize_t n_rpadding) -{ - Py_ssize_t pos; - - /* Pad on left. */ - if (n_lpadding) { - pos = writer->pos; - _PyUnicode_FastFill(writer->buffer, pos, n_lpadding, fill_char); - } - - /* Pad on right. */ - if (n_rpadding) { - pos = writer->pos + nchars + n_lpadding; - _PyUnicode_FastFill(writer->buffer, pos, n_rpadding, fill_char); - } - - /* Pointer to the user content. */ - writer->pos += n_lpadding; - return 0; -} - -/************************************************************************/ -/*********** common routines for numeric formatting *********************/ -/************************************************************************/ - -/* Locale info needed for formatting integers and the part of floats - before and including the decimal. Note that locales only support - 8-bit chars, not unicode. */ -typedef struct { - PyObject *decimal_point; - PyObject *thousands_sep; - const char *grouping; - char *grouping_buffer; -} LocaleInfo; - -#define LocaleInfo_STATIC_INIT {0, 0, 0, 0} - -/* describes the layout for an integer, see the comment in - calc_number_widths() for details */ -typedef struct { - Py_ssize_t n_lpadding; - Py_ssize_t n_prefix; - Py_ssize_t n_spadding; - Py_ssize_t n_rpadding; - char sign; - Py_ssize_t n_sign; /* number of digits needed for sign (0/1) */ - Py_ssize_t n_grouped_digits; /* Space taken up by the digits, including - any grouping chars. */ - Py_ssize_t n_decimal; /* 0 if only an integer */ - Py_ssize_t n_remainder; /* Digits in decimal and/or exponent part, - excluding the decimal itself, if - present. */ - - /* These 2 are not the widths of fields, but are needed by - STRINGLIB_GROUPING. */ - Py_ssize_t n_digits; /* The number of digits before a decimal - or exponent. */ - Py_ssize_t n_min_width; /* The min_width we used when we computed - the n_grouped_digits width. */ -} NumberFieldWidths; - - -/* Given a number of the form: - digits[remainder] - where ptr points to the start and end points to the end, find where - the integer part ends. This could be a decimal, an exponent, both, - or neither. - If a decimal point is present, set *has_decimal and increment - remainder beyond it. - Results are undefined (but shouldn't crash) for improperly - formatted strings. -*/ -static void -parse_number(PyObject *s, Py_ssize_t pos, Py_ssize_t end, - Py_ssize_t *n_remainder, int *has_decimal) -{ - Py_ssize_t remainder; - int kind = PyUnicode_KIND(s); - const void *data = PyUnicode_DATA(s); - - while (pos<end && Py_ISDIGIT(PyUnicode_READ(kind, data, pos))) - ++pos; - remainder = pos; - - /* Does remainder start with a decimal point? */ - *has_decimal = pos<end && PyUnicode_READ(kind, data, remainder) == '.'; - - /* Skip the decimal point. */ - if (*has_decimal) - remainder++; - - *n_remainder = end - remainder; -} - -/* not all fields of format are used. for example, precision is - unused. should this take discrete params in order to be more clear - about what it does? or is passing a single format parameter easier - and more efficient enough to justify a little obfuscation? - Return -1 on error. */ -static Py_ssize_t -calc_number_widths(NumberFieldWidths *spec, Py_ssize_t n_prefix, - Py_UCS4 sign_char, Py_ssize_t n_start, - Py_ssize_t n_end, Py_ssize_t n_remainder, - int has_decimal, const LocaleInfo *locale, - const InternalFormatSpec *format, Py_UCS4 *maxchar) -{ - Py_ssize_t n_non_digit_non_padding; - Py_ssize_t n_padding; - - spec->n_digits = n_end - n_start - n_remainder - (has_decimal?1:0); - spec->n_lpadding = 0; - spec->n_prefix = n_prefix; - spec->n_decimal = has_decimal ? PyUnicode_GET_LENGTH(locale->decimal_point) : 0; - spec->n_remainder = n_remainder; - spec->n_spadding = 0; - spec->n_rpadding = 0; - spec->sign = '\0'; - spec->n_sign = 0; - - /* the output will look like: - | | - | <lpadding> <sign> <prefix> <spadding> <grouped_digits> <decimal> <remainder> <rpadding> | - | | - - sign is computed from format->sign and the actual - sign of the number - - prefix is given (it's for the '0x' prefix) - - digits is already known - - the total width is either given, or computed from the - actual digits - - only one of lpadding, spadding, and rpadding can be non-zero, - and it's calculated from the width and other fields - */ - - /* compute the various parts we're going to write */ - switch (format->sign) { - case '+': - /* always put a + or - */ - spec->n_sign = 1; - spec->sign = (sign_char == '-' ? '-' : '+'); - break; - case ' ': - spec->n_sign = 1; - spec->sign = (sign_char == '-' ? '-' : ' '); - break; - default: - /* Not specified, or the default (-) */ - if (sign_char == '-') { - spec->n_sign = 1; - spec->sign = '-'; - } - } - - /* The number of chars used for non-digits and non-padding. */ - n_non_digit_non_padding = spec->n_sign + spec->n_prefix + spec->n_decimal + - spec->n_remainder; - - /* min_width can go negative, that's okay. format->width == -1 means - we don't care. */ - if (format->fill_char == '0' && format->align == '=') - spec->n_min_width = format->width - n_non_digit_non_padding; - else - spec->n_min_width = 0; - - if (spec->n_digits == 0) - /* This case only occurs when using 'c' formatting, we need - to special case it because the grouping code always wants - to have at least one character. */ - spec->n_grouped_digits = 0; - else { - Py_UCS4 grouping_maxchar; - spec->n_grouped_digits = _PyUnicode_InsertThousandsGrouping( - NULL, 0, - NULL, 0, spec->n_digits, - spec->n_min_width, - locale->grouping, locale->thousands_sep, &grouping_maxchar); - if (spec->n_grouped_digits == -1) { - return -1; - } - *maxchar = Py_MAX(*maxchar, grouping_maxchar); - } - - /* Given the desired width and the total of digit and non-digit - space we consume, see if we need any padding. format->width can - be negative (meaning no padding), but this code still works in - that case. */ - n_padding = format->width - - (n_non_digit_non_padding + spec->n_grouped_digits); - if (n_padding > 0) { - /* Some padding is needed. Determine if it's left, space, or right. */ - switch (format->align) { - case '<': - spec->n_rpadding = n_padding; - break; - case '^': - spec->n_lpadding = n_padding / 2; - spec->n_rpadding = n_padding - spec->n_lpadding; - break; - case '=': - spec->n_spadding = n_padding; - break; - case '>': - spec->n_lpadding = n_padding; - break; - default: - /* Shouldn't get here */ - Py_UNREACHABLE(); - } - } - - if (spec->n_lpadding || spec->n_spadding || spec->n_rpadding) - *maxchar = Py_MAX(*maxchar, format->fill_char); - - if (spec->n_decimal) - *maxchar = Py_MAX(*maxchar, PyUnicode_MAX_CHAR_VALUE(locale->decimal_point)); - - return spec->n_lpadding + spec->n_sign + spec->n_prefix + - spec->n_spadding + spec->n_grouped_digits + spec->n_decimal + - spec->n_remainder + spec->n_rpadding; -} - -/* Fill in the digit parts of a number's string representation, - as determined in calc_number_widths(). - Return -1 on error, or 0 on success. */ -static int -fill_number(_PyUnicodeWriter *writer, const NumberFieldWidths *spec, - PyObject *digits, Py_ssize_t d_start, - PyObject *prefix, Py_ssize_t p_start, - Py_UCS4 fill_char, - LocaleInfo *locale, int toupper) -{ - /* Used to keep track of digits, decimal, and remainder. */ - Py_ssize_t d_pos = d_start; - const unsigned int kind = writer->kind; - const void *data = writer->data; - Py_ssize_t r; - - if (spec->n_lpadding) { - _PyUnicode_FastFill(writer->buffer, - writer->pos, spec->n_lpadding, fill_char); - writer->pos += spec->n_lpadding; - } - if (spec->n_sign == 1) { - PyUnicode_WRITE(kind, data, writer->pos, spec->sign); - writer->pos++; - } - if (spec->n_prefix) { - _PyUnicode_FastCopyCharacters(writer->buffer, writer->pos, - prefix, p_start, - spec->n_prefix); - if (toupper) { - Py_ssize_t t; - for (t = 0; t < spec->n_prefix; t++) { - Py_UCS4 c = PyUnicode_READ(kind, data, writer->pos + t); - c = Py_TOUPPER(c); - assert (c <= 127); - PyUnicode_WRITE(kind, data, writer->pos + t, c); - } - } - writer->pos += spec->n_prefix; - } - if (spec->n_spadding) { - _PyUnicode_FastFill(writer->buffer, - writer->pos, spec->n_spadding, fill_char); - writer->pos += spec->n_spadding; - } - - /* Only for type 'c' special case, it has no digits. */ - if (spec->n_digits != 0) { - /* Fill the digits with InsertThousandsGrouping. */ - r = _PyUnicode_InsertThousandsGrouping( - writer, spec->n_grouped_digits, - digits, d_pos, spec->n_digits, - spec->n_min_width, - locale->grouping, locale->thousands_sep, NULL); - if (r == -1) - return -1; - assert(r == spec->n_grouped_digits); - d_pos += spec->n_digits; - } - if (toupper) { - Py_ssize_t t; - for (t = 0; t < spec->n_grouped_digits; t++) { - Py_UCS4 c = PyUnicode_READ(kind, data, writer->pos + t); - c = Py_TOUPPER(c); - if (c > 127) { - PyErr_SetString(PyExc_SystemError, "non-ascii grouped digit"); - return -1; - } - PyUnicode_WRITE(kind, data, writer->pos + t, c); - } - } - writer->pos += spec->n_grouped_digits; - - if (spec->n_decimal) { - _PyUnicode_FastCopyCharacters( - writer->buffer, writer->pos, - locale->decimal_point, 0, spec->n_decimal); - writer->pos += spec->n_decimal; - d_pos += 1; - } - - if (spec->n_remainder) { - _PyUnicode_FastCopyCharacters( - writer->buffer, writer->pos, - digits, d_pos, spec->n_remainder); - writer->pos += spec->n_remainder; - /* d_pos += spec->n_remainder; */ - } - - if (spec->n_rpadding) { - _PyUnicode_FastFill(writer->buffer, - writer->pos, spec->n_rpadding, - fill_char); - writer->pos += spec->n_rpadding; - } - return 0; -} - -static const char no_grouping[1] = {CHAR_MAX}; - -/* Find the decimal point character(s?), thousands_separator(s?), and - grouping description, either for the current locale if type is - LT_CURRENT_LOCALE, a hard-coded locale if LT_DEFAULT_LOCALE or - LT_UNDERSCORE_LOCALE/LT_UNDER_FOUR_LOCALE, or none if LT_NO_LOCALE. */ -static int -get_locale_info(enum LocaleType type, LocaleInfo *locale_info) -{ - switch (type) { - case LT_CURRENT_LOCALE: { - struct lconv *lc = localeconv(); - if (_Py_GetLocaleconvNumeric(lc, - &locale_info->decimal_point, - &locale_info->thousands_sep) < 0) { - return -1; - } - - /* localeconv() grouping can become a dangling pointer or point - to a different string if another thread calls localeconv() during - the string formatting. Copy the string to avoid this risk. */ - locale_info->grouping_buffer = _PyMem_Strdup(lc->grouping); - if (locale_info->grouping_buffer == NULL) { - PyErr_NoMemory(); - return -1; - } - locale_info->grouping = locale_info->grouping_buffer; - break; - } - case LT_DEFAULT_LOCALE: - case LT_UNDERSCORE_LOCALE: - case LT_UNDER_FOUR_LOCALE: - locale_info->decimal_point = PyUnicode_FromOrdinal('.'); - locale_info->thousands_sep = PyUnicode_FromOrdinal( - type == LT_DEFAULT_LOCALE ? ',' : '_'); - if (!locale_info->decimal_point || !locale_info->thousands_sep) - return -1; - if (type != LT_UNDER_FOUR_LOCALE) - locale_info->grouping = "\3"; /* Group every 3 characters. The - (implicit) trailing 0 means repeat - infinitely. */ - else - locale_info->grouping = "\4"; /* Bin/oct/hex group every four. */ - break; - case LT_NO_LOCALE: - locale_info->decimal_point = PyUnicode_FromOrdinal('.'); - locale_info->thousands_sep = PyUnicode_New(0, 0); - if (!locale_info->decimal_point || !locale_info->thousands_sep) - return -1; - locale_info->grouping = no_grouping; - break; - } - return 0; -} - -static void -free_locale_info(LocaleInfo *locale_info) -{ - Py_XDECREF(locale_info->decimal_point); - Py_XDECREF(locale_info->thousands_sep); - PyMem_Free(locale_info->grouping_buffer); -} - -/************************************************************************/ -/*********** string formatting ******************************************/ -/************************************************************************/ - -static int -format_string_internal(PyObject *value, const InternalFormatSpec *format, - _PyUnicodeWriter *writer) -{ - Py_ssize_t lpad; - Py_ssize_t rpad; - Py_ssize_t total; - Py_ssize_t len; - int result = -1; - Py_UCS4 maxchar; - - assert(PyUnicode_IS_READY(value)); - len = PyUnicode_GET_LENGTH(value); - - /* sign is not allowed on strings */ - if (format->sign != '\0') { - if (format->sign == ' ') { - PyErr_SetString(PyExc_ValueError, - "Space not allowed in string format specifier"); - } - else { - PyErr_SetString(PyExc_ValueError, - "Sign not allowed in string format specifier"); - } - goto done; - } - - /* alternate is not allowed on strings */ - if (format->alternate) { - PyErr_SetString(PyExc_ValueError, - "Alternate form (#) not allowed in string format " - "specifier"); - goto done; - } - - /* '=' alignment not allowed on strings */ - if (format->align == '=') { - PyErr_SetString(PyExc_ValueError, - "'=' alignment not allowed " - "in string format specifier"); - goto done; - } - - if ((format->width == -1 || format->width <= len) - && (format->precision == -1 || format->precision >= len)) { - /* Fast path */ - return _PyUnicodeWriter_WriteStr(writer, value); - } - - /* if precision is specified, output no more that format.precision - characters */ - if (format->precision >= 0 && len >= format->precision) { - len = format->precision; - } - - calc_padding(len, format->width, format->align, &lpad, &rpad, &total); - - maxchar = writer->maxchar; - if (lpad != 0 || rpad != 0) - maxchar = Py_MAX(maxchar, format->fill_char); - if (PyUnicode_MAX_CHAR_VALUE(value) > maxchar) { - Py_UCS4 valmaxchar = _PyUnicode_FindMaxChar(value, 0, len); - maxchar = Py_MAX(maxchar, valmaxchar); - } - - /* allocate the resulting string */ - if (_PyUnicodeWriter_Prepare(writer, total, maxchar) == -1) - goto done; - - /* Write into that space. First the padding. */ - result = fill_padding(writer, len, format->fill_char, lpad, rpad); - if (result == -1) - goto done; - - /* Then the source string. */ - if (len) { - _PyUnicode_FastCopyCharacters(writer->buffer, writer->pos, - value, 0, len); - } - writer->pos += (len + rpad); - result = 0; - -done: - return result; -} - - -/************************************************************************/ -/*********** long formatting ********************************************/ -/************************************************************************/ - -static int -format_long_internal(PyObject *value, const InternalFormatSpec *format, - _PyUnicodeWriter *writer) -{ - int result = -1; - Py_UCS4 maxchar = 127; - PyObject *tmp = NULL; - Py_ssize_t inumeric_chars; - Py_UCS4 sign_char = '\0'; - Py_ssize_t n_digits; /* count of digits need from the computed - string */ - Py_ssize_t n_remainder = 0; /* Used only for 'c' formatting, which - produces non-digits */ - Py_ssize_t n_prefix = 0; /* Count of prefix chars, (e.g., '0x') */ - Py_ssize_t n_total; - Py_ssize_t prefix = 0; - NumberFieldWidths spec; - long x; - - /* Locale settings, either from the actual locale or - from a hard-code pseudo-locale */ - LocaleInfo locale = LocaleInfo_STATIC_INIT; - - /* no precision allowed on integers */ - if (format->precision != -1) { - PyErr_SetString(PyExc_ValueError, - "Precision not allowed in integer format specifier"); - goto done; - } - - /* special case for character formatting */ - if (format->type == 'c') { - /* error to specify a sign */ - if (format->sign != '\0') { - PyErr_SetString(PyExc_ValueError, - "Sign not allowed with integer" - " format specifier 'c'"); - goto done; - } - /* error to request alternate format */ - if (format->alternate) { - PyErr_SetString(PyExc_ValueError, - "Alternate form (#) not allowed with integer" - " format specifier 'c'"); - goto done; - } - - /* taken from unicodeobject.c formatchar() */ - /* Integer input truncated to a character */ - x = PyLong_AsLong(value); - if (x == -1 && PyErr_Occurred()) - goto done; - if (x < 0 || x > 0x10ffff) { - PyErr_SetString(PyExc_OverflowError, - "%c arg not in range(0x110000)"); - goto done; - } - tmp = PyUnicode_FromOrdinal(x); - inumeric_chars = 0; - n_digits = 1; - maxchar = Py_MAX(maxchar, (Py_UCS4)x); - - /* As a sort-of hack, we tell calc_number_widths that we only - have "remainder" characters. calc_number_widths thinks - these are characters that don't get formatted, only copied - into the output string. We do this for 'c' formatting, - because the characters are likely to be non-digits. */ - n_remainder = 1; - } - else { - int base; - int leading_chars_to_skip = 0; /* Number of characters added by - PyNumber_ToBase that we want to - skip over. */ - - /* Compute the base and how many characters will be added by - PyNumber_ToBase */ - switch (format->type) { - case 'b': - base = 2; - leading_chars_to_skip = 2; /* 0b */ - break; - case 'o': - base = 8; - leading_chars_to_skip = 2; /* 0o */ - break; - case 'x': - case 'X': - base = 16; - leading_chars_to_skip = 2; /* 0x */ - break; - default: /* shouldn't be needed, but stops a compiler warning */ - case 'd': - case 'n': - base = 10; - break; - } - - if (format->sign != '+' && format->sign != ' ' - && format->width == -1 - && format->type != 'X' && format->type != 'n' - && !format->thousands_separators - && PyLong_CheckExact(value)) - { - /* Fast path */ - return _PyLong_FormatWriter(writer, value, base, format->alternate); - } - - /* The number of prefix chars is the same as the leading - chars to skip */ - if (format->alternate) - n_prefix = leading_chars_to_skip; - - /* Do the hard part, converting to a string in a given base */ - tmp = _PyLong_Format(value, base); - if (tmp == NULL || PyUnicode_READY(tmp) == -1) - goto done; - - inumeric_chars = 0; - n_digits = PyUnicode_GET_LENGTH(tmp); - - prefix = inumeric_chars; - - /* Is a sign character present in the output? If so, remember it - and skip it */ - if (PyUnicode_READ_CHAR(tmp, inumeric_chars) == '-') { - sign_char = '-'; - ++prefix; - ++leading_chars_to_skip; - } - - /* Skip over the leading chars (0x, 0b, etc.) */ - n_digits -= leading_chars_to_skip; - inumeric_chars += leading_chars_to_skip; - } - - /* Determine the grouping, separator, and decimal point, if any. */ - if (get_locale_info(format->type == 'n' ? LT_CURRENT_LOCALE : - format->thousands_separators, - &locale) == -1) - goto done; - - /* Calculate how much memory we'll need. */ - n_total = calc_number_widths(&spec, n_prefix, sign_char, inumeric_chars, - inumeric_chars + n_digits, n_remainder, 0, - &locale, format, &maxchar); - if (n_total == -1) { - goto done; - } - - /* Allocate the memory. */ - if (_PyUnicodeWriter_Prepare(writer, n_total, maxchar) == -1) - goto done; - - /* Populate the memory. */ - result = fill_number(writer, &spec, - tmp, inumeric_chars, - tmp, prefix, format->fill_char, - &locale, format->type == 'X'); - -done: - Py_XDECREF(tmp); - free_locale_info(&locale); - return result; -} - -/************************************************************************/ -/*********** float formatting *******************************************/ -/************************************************************************/ - -/* much of this is taken from unicodeobject.c */ -static int -format_float_internal(PyObject *value, - const InternalFormatSpec *format, - _PyUnicodeWriter *writer) -{ - char *buf = NULL; /* buffer returned from PyOS_double_to_string */ - Py_ssize_t n_digits; - Py_ssize_t n_remainder; - Py_ssize_t n_total; - int has_decimal; - double val; - int precision, default_precision = 6; - Py_UCS4 type = format->type; - int add_pct = 0; - Py_ssize_t index; - NumberFieldWidths spec; - int flags = 0; - int result = -1; - Py_UCS4 maxchar = 127; - Py_UCS4 sign_char = '\0'; - int float_type; /* Used to see if we have a nan, inf, or regular float. */ - PyObject *unicode_tmp = NULL; - - /* Locale settings, either from the actual locale or - from a hard-code pseudo-locale */ - LocaleInfo locale = LocaleInfo_STATIC_INIT; - - if (format->precision > INT_MAX) { - PyErr_SetString(PyExc_ValueError, "precision too big"); - goto done; - } - precision = (int)format->precision; - - if (format->alternate) - flags |= Py_DTSF_ALT; - - if (type == '\0') { - /* Omitted type specifier. Behaves in the same way as repr(x) - and str(x) if no precision is given, else like 'g', but with - at least one digit after the decimal point. */ - flags |= Py_DTSF_ADD_DOT_0; - type = 'r'; - default_precision = 0; - } - - if (type == 'n') - /* 'n' is the same as 'g', except for the locale used to - format the result. We take care of that later. */ - type = 'g'; - - val = PyFloat_AsDouble(value); - if (val == -1.0 && PyErr_Occurred()) - goto done; - - if (type == '%') { - type = 'f'; - val *= 100; - add_pct = 1; - } - - if (precision < 0) - precision = default_precision; - else if (type == 'r') - type = 'g'; - - /* Cast "type", because if we're in unicode we need to pass an - 8-bit char. This is safe, because we've restricted what "type" - can be. */ - buf = PyOS_double_to_string(val, (char)type, precision, flags, - &float_type); - if (buf == NULL) - goto done; - n_digits = strlen(buf); - - if (add_pct) { - /* We know that buf has a trailing zero (since we just called - strlen() on it), and we don't use that fact any more. So we - can just write over the trailing zero. */ - buf[n_digits] = '%'; - n_digits += 1; - } - - if (format->sign != '+' && format->sign != ' ' - && format->width == -1 - && format->type != 'n' - && !format->thousands_separators) - { - /* Fast path */ - result = _PyUnicodeWriter_WriteASCIIString(writer, buf, n_digits); - PyMem_Free(buf); - return result; - } - - /* Since there is no unicode version of PyOS_double_to_string, - just use the 8 bit version and then convert to unicode. */ - unicode_tmp = _PyUnicode_FromASCII(buf, n_digits); - PyMem_Free(buf); - if (unicode_tmp == NULL) - goto done; - - /* Is a sign character present in the output? If so, remember it - and skip it */ - index = 0; - if (PyUnicode_READ_CHAR(unicode_tmp, index) == '-') { - sign_char = '-'; - ++index; - --n_digits; - } - - /* Determine if we have any "remainder" (after the digits, might include - decimal or exponent or both (or neither)) */ - parse_number(unicode_tmp, index, index + n_digits, &n_remainder, &has_decimal); - - /* Determine the grouping, separator, and decimal point, if any. */ - if (get_locale_info(format->type == 'n' ? LT_CURRENT_LOCALE : - format->thousands_separators, - &locale) == -1) - goto done; - - /* Calculate how much memory we'll need. */ - n_total = calc_number_widths(&spec, 0, sign_char, index, - index + n_digits, n_remainder, has_decimal, - &locale, format, &maxchar); - if (n_total == -1) { - goto done; - } - - /* Allocate the memory. */ - if (_PyUnicodeWriter_Prepare(writer, n_total, maxchar) == -1) - goto done; - - /* Populate the memory. */ - result = fill_number(writer, &spec, - unicode_tmp, index, - NULL, 0, format->fill_char, - &locale, 0); - -done: - Py_XDECREF(unicode_tmp); - free_locale_info(&locale); - return result; -} - -/************************************************************************/ -/*********** complex formatting *****************************************/ -/************************************************************************/ - -static int -format_complex_internal(PyObject *value, - const InternalFormatSpec *format, - _PyUnicodeWriter *writer) -{ - double re; - double im; - char *re_buf = NULL; /* buffer returned from PyOS_double_to_string */ - char *im_buf = NULL; /* buffer returned from PyOS_double_to_string */ - - InternalFormatSpec tmp_format = *format; - Py_ssize_t n_re_digits; - Py_ssize_t n_im_digits; - Py_ssize_t n_re_remainder; - Py_ssize_t n_im_remainder; - Py_ssize_t n_re_total; - Py_ssize_t n_im_total; - int re_has_decimal; - int im_has_decimal; - int precision, default_precision = 6; - Py_UCS4 type = format->type; - Py_ssize_t i_re; - Py_ssize_t i_im; - NumberFieldWidths re_spec; - NumberFieldWidths im_spec; - int flags = 0; - int result = -1; - Py_UCS4 maxchar = 127; - enum PyUnicode_Kind rkind; - void *rdata; - Py_UCS4 re_sign_char = '\0'; - Py_UCS4 im_sign_char = '\0'; - int re_float_type; /* Used to see if we have a nan, inf, or regular float. */ - int im_float_type; - int add_parens = 0; - int skip_re = 0; - Py_ssize_t lpad; - Py_ssize_t rpad; - Py_ssize_t total; - PyObject *re_unicode_tmp = NULL; - PyObject *im_unicode_tmp = NULL; - - /* Locale settings, either from the actual locale or - from a hard-code pseudo-locale */ - LocaleInfo locale = LocaleInfo_STATIC_INIT; - - if (format->precision > INT_MAX) { - PyErr_SetString(PyExc_ValueError, "precision too big"); - goto done; - } - precision = (int)format->precision; - - /* Zero padding is not allowed. */ - if (format->fill_char == '0') { - PyErr_SetString(PyExc_ValueError, - "Zero padding is not allowed in complex format " - "specifier"); - goto done; - } - - /* Neither is '=' alignment . */ - if (format->align == '=') { - PyErr_SetString(PyExc_ValueError, - "'=' alignment flag is not allowed in complex format " - "specifier"); - goto done; - } - - re = PyComplex_RealAsDouble(value); - if (re == -1.0 && PyErr_Occurred()) - goto done; - im = PyComplex_ImagAsDouble(value); - if (im == -1.0 && PyErr_Occurred()) - goto done; - - if (format->alternate) - flags |= Py_DTSF_ALT; - - if (type == '\0') { - /* Omitted type specifier. Should be like str(self). */ - type = 'r'; - default_precision = 0; - if (re == 0.0 && copysign(1.0, re) == 1.0) - skip_re = 1; - else - add_parens = 1; - } - - if (type == 'n') - /* 'n' is the same as 'g', except for the locale used to - format the result. We take care of that later. */ - type = 'g'; - - if (precision < 0) - precision = default_precision; - else if (type == 'r') - type = 'g'; - - /* Cast "type", because if we're in unicode we need to pass an - 8-bit char. This is safe, because we've restricted what "type" - can be. */ - re_buf = PyOS_double_to_string(re, (char)type, precision, flags, - &re_float_type); - if (re_buf == NULL) - goto done; - im_buf = PyOS_double_to_string(im, (char)type, precision, flags, - &im_float_type); - if (im_buf == NULL) - goto done; - - n_re_digits = strlen(re_buf); - n_im_digits = strlen(im_buf); - - /* Since there is no unicode version of PyOS_double_to_string, - just use the 8 bit version and then convert to unicode. */ - re_unicode_tmp = _PyUnicode_FromASCII(re_buf, n_re_digits); - if (re_unicode_tmp == NULL) - goto done; - i_re = 0; - - im_unicode_tmp = _PyUnicode_FromASCII(im_buf, n_im_digits); - if (im_unicode_tmp == NULL) - goto done; - i_im = 0; - - /* Is a sign character present in the output? If so, remember it - and skip it */ - if (PyUnicode_READ_CHAR(re_unicode_tmp, i_re) == '-') { - re_sign_char = '-'; - ++i_re; - --n_re_digits; - } - if (PyUnicode_READ_CHAR(im_unicode_tmp, i_im) == '-') { - im_sign_char = '-'; - ++i_im; - --n_im_digits; - } - - /* Determine if we have any "remainder" (after the digits, might include - decimal or exponent or both (or neither)) */ - parse_number(re_unicode_tmp, i_re, i_re + n_re_digits, - &n_re_remainder, &re_has_decimal); - parse_number(im_unicode_tmp, i_im, i_im + n_im_digits, - &n_im_remainder, &im_has_decimal); - - /* Determine the grouping, separator, and decimal point, if any. */ - if (get_locale_info(format->type == 'n' ? LT_CURRENT_LOCALE : - format->thousands_separators, - &locale) == -1) - goto done; - - /* Turn off any padding. We'll do it later after we've composed - the numbers without padding. */ - tmp_format.fill_char = '\0'; - tmp_format.align = '<'; - tmp_format.width = -1; - - /* Calculate how much memory we'll need. */ - n_re_total = calc_number_widths(&re_spec, 0, re_sign_char, - i_re, i_re + n_re_digits, n_re_remainder, - re_has_decimal, &locale, &tmp_format, - &maxchar); - if (n_re_total == -1) { - goto done; - } - - /* Same formatting, but always include a sign, unless the real part is - * going to be omitted, in which case we use whatever sign convention was - * requested by the original format. */ - if (!skip_re) - tmp_format.sign = '+'; - n_im_total = calc_number_widths(&im_spec, 0, im_sign_char, - i_im, i_im + n_im_digits, n_im_remainder, - im_has_decimal, &locale, &tmp_format, - &maxchar); - if (n_im_total == -1) { - goto done; - } - - if (skip_re) - n_re_total = 0; - - /* Add 1 for the 'j', and optionally 2 for parens. */ - calc_padding(n_re_total + n_im_total + 1 + add_parens * 2, - format->width, format->align, &lpad, &rpad, &total); - - if (lpad || rpad) - maxchar = Py_MAX(maxchar, format->fill_char); - - if (_PyUnicodeWriter_Prepare(writer, total, maxchar) == -1) - goto done; - rkind = writer->kind; - rdata = writer->data; - - /* Populate the memory. First, the padding. */ - result = fill_padding(writer, - n_re_total + n_im_total + 1 + add_parens * 2, - format->fill_char, lpad, rpad); - if (result == -1) - goto done; - - if (add_parens) { - PyUnicode_WRITE(rkind, rdata, writer->pos, '('); - writer->pos++; - } - - if (!skip_re) { - result = fill_number(writer, &re_spec, - re_unicode_tmp, i_re, - NULL, 0, - 0, - &locale, 0); - if (result == -1) - goto done; - } - result = fill_number(writer, &im_spec, - im_unicode_tmp, i_im, - NULL, 0, - 0, - &locale, 0); - if (result == -1) - goto done; - PyUnicode_WRITE(rkind, rdata, writer->pos, 'j'); - writer->pos++; - - if (add_parens) { - PyUnicode_WRITE(rkind, rdata, writer->pos, ')'); - writer->pos++; - } - - writer->pos += rpad; - -done: - PyMem_Free(re_buf); - PyMem_Free(im_buf); - Py_XDECREF(re_unicode_tmp); - Py_XDECREF(im_unicode_tmp); - free_locale_info(&locale); - return result; -} - -/************************************************************************/ -/*********** built in formatters ****************************************/ -/************************************************************************/ -static int -format_obj(PyObject *obj, _PyUnicodeWriter *writer) -{ - PyObject *str; - int err; - - str = PyObject_Str(obj); - if (str == NULL) - return -1; - err = _PyUnicodeWriter_WriteStr(writer, str); - Py_DECREF(str); - return err; -} - -int -_PyUnicode_FormatAdvancedWriter(_PyUnicodeWriter *writer, - PyObject *obj, - PyObject *format_spec, - Py_ssize_t start, Py_ssize_t end) -{ - InternalFormatSpec format; - - assert(PyUnicode_Check(obj)); - - /* check for the special case of zero length format spec, make - it equivalent to str(obj) */ - if (start == end) { - if (PyUnicode_CheckExact(obj)) - return _PyUnicodeWriter_WriteStr(writer, obj); - else - return format_obj(obj, writer); - } - - /* parse the format_spec */ - if (!parse_internal_render_format_spec(format_spec, start, end, - &format, 's', '<')) - return -1; - - /* type conversion? */ - switch (format.type) { - case 's': - /* no type conversion needed, already a string. do the formatting */ - return format_string_internal(obj, &format, writer); - default: - /* unknown */ - unknown_presentation_type(format.type, Py_TYPE(obj)->tp_name); - return -1; - } -} - -int -_PyLong_FormatAdvancedWriter(_PyUnicodeWriter *writer, - PyObject *obj, - PyObject *format_spec, - Py_ssize_t start, Py_ssize_t end) -{ - PyObject *tmp = NULL; - InternalFormatSpec format; - int result = -1; - - /* check for the special case of zero length format spec, make - it equivalent to str(obj) */ - if (start == end) { - if (PyLong_CheckExact(obj)) - return _PyLong_FormatWriter(writer, obj, 10, 0); - else - return format_obj(obj, writer); - } - - /* parse the format_spec */ - if (!parse_internal_render_format_spec(format_spec, start, end, - &format, 'd', '>')) - goto done; - - /* type conversion? */ - switch (format.type) { - case 'b': - case 'c': - case 'd': - case 'o': - case 'x': - case 'X': - case 'n': - /* no type conversion needed, already an int. do the formatting */ - result = format_long_internal(obj, &format, writer); - break; - - case 'e': - case 'E': - case 'f': - case 'F': - case 'g': - case 'G': - case '%': - /* convert to float */ - tmp = PyNumber_Float(obj); - if (tmp == NULL) - goto done; - result = format_float_internal(tmp, &format, writer); - break; - - default: - /* unknown */ - unknown_presentation_type(format.type, Py_TYPE(obj)->tp_name); - goto done; - } - -done: - Py_XDECREF(tmp); - return result; -} - -int -_PyFloat_FormatAdvancedWriter(_PyUnicodeWriter *writer, - PyObject *obj, - PyObject *format_spec, - Py_ssize_t start, Py_ssize_t end) -{ - InternalFormatSpec format; - - /* check for the special case of zero length format spec, make - it equivalent to str(obj) */ - if (start == end) - return format_obj(obj, writer); - - /* parse the format_spec */ - if (!parse_internal_render_format_spec(format_spec, start, end, - &format, '\0', '>')) - return -1; - - /* type conversion? */ - switch (format.type) { - case '\0': /* No format code: like 'g', but with at least one decimal. */ - case 'e': - case 'E': - case 'f': - case 'F': - case 'g': - case 'G': - case 'n': - case '%': - /* no conversion, already a float. do the formatting */ - return format_float_internal(obj, &format, writer); - - default: - /* unknown */ - unknown_presentation_type(format.type, Py_TYPE(obj)->tp_name); - return -1; - } -} - -int -_PyComplex_FormatAdvancedWriter(_PyUnicodeWriter *writer, - PyObject *obj, - PyObject *format_spec, - Py_ssize_t start, Py_ssize_t end) -{ - InternalFormatSpec format; - - /* check for the special case of zero length format spec, make - it equivalent to str(obj) */ - if (start == end) - return format_obj(obj, writer); - - /* parse the format_spec */ - if (!parse_internal_render_format_spec(format_spec, start, end, - &format, '\0', '>')) - return -1; - - /* type conversion? */ - switch (format.type) { - case '\0': /* No format code: like 'g', but with at least one decimal. */ - case 'e': - case 'E': - case 'f': - case 'F': - case 'g': - case 'G': - case 'n': - /* no conversion, already a complex. do the formatting */ - return format_complex_internal(obj, &format, writer); - - default: - /* unknown */ - unknown_presentation_type(format.type, Py_TYPE(obj)->tp_name); - return -1; - } -} diff --git a/contrib/tools/python3/src/Python/frozen.c b/contrib/tools/python3/src/Python/frozen.c deleted file mode 100644 index 7f433ff80ca..00000000000 --- a/contrib/tools/python3/src/Python/frozen.c +++ /dev/null @@ -1,39 +0,0 @@ - -/* Frozen modules initializer */ - -#include "Python.h" -#include "importlib.h" -#include "importlib_external.h" -#include "importlib_zipimport.h" - -/* In order to test the support for frozen modules, by default we - define a single frozen module, __hello__. Loading it will print - some famous words... */ - -/* Run "make regen-frozen" to regen the file below (e.g. after a bytecode - * format change). The include file defines _Py_M__hello as an array of bytes. - */ -#include "frozen_hello.h" - -#define SIZE (int)sizeof(_Py_M__hello) - -static const struct _frozen _PyImport_FrozenModules[] = { - /* importlib */ - {"_frozen_importlib", _Py_M__importlib_bootstrap, - (int)sizeof(_Py_M__importlib_bootstrap)}, - {"_frozen_importlib_external", _Py_M__importlib_bootstrap_external, - (int)sizeof(_Py_M__importlib_bootstrap_external)}, - {"zipimport", _Py_M__zipimport, - (int)sizeof(_Py_M__zipimport)}, - /* Test module */ - {"__hello__", _Py_M__hello, SIZE}, - /* Test package (negative size indicates package-ness) */ - {"__phello__", _Py_M__hello, -SIZE}, - {"__phello__.spam", _Py_M__hello, SIZE}, - {0, 0, 0} /* sentinel */ -}; - -/* Embedding apps may change this pointer to point to their favorite - collection of frozen modules: */ - -const struct _frozen *PyImport_FrozenModules = _PyImport_FrozenModules; diff --git a/contrib/tools/python3/src/Python/frozen_hello.h b/contrib/tools/python3/src/Python/frozen_hello.h deleted file mode 100644 index 5448c80daa4..00000000000 --- a/contrib/tools/python3/src/Python/frozen_hello.h +++ /dev/null @@ -1,12 +0,0 @@ -/* Auto-generated by Programs/_freeze_importlib.c */ -const unsigned char _Py_M__hello[] = { - 99,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,2,0,0,0,64,0,0,0,115,16,0,0,0,100,0, - 90,0,101,1,100,1,131,1,1,0,100,2,83,0,41,3, - 84,122,12,72,101,108,108,111,32,119,111,114,108,100,33,78, - 41,2,90,11,105,110,105,116,105,97,108,105,122,101,100,218, - 5,112,114,105,110,116,169,0,114,1,0,0,0,114,1,0, - 0,0,122,14,60,102,114,111,122,101,110,32,104,101,108,108, - 111,62,218,8,60,109,111,100,117,108,101,62,1,0,0,0, - 115,4,0,0,0,4,0,12,1, -}; diff --git a/contrib/tools/python3/src/Python/frozenmain.c b/contrib/tools/python3/src/Python/frozenmain.c deleted file mode 100644 index dd04d609d24..00000000000 --- a/contrib/tools/python3/src/Python/frozenmain.c +++ /dev/null @@ -1,129 +0,0 @@ - -/* Python interpreter main program for frozen scripts */ - -#include "Python.h" -#include "pycore_runtime.h" // _PyRuntime_Initialize() -#include <locale.h> - -#ifdef MS_WINDOWS -extern void PyWinFreeze_ExeInit(void); -extern void PyWinFreeze_ExeTerm(void); -extern int PyInitFrozenExtensions(void); -#endif - -/* Main program */ - -int -Py_FrozenMain(int argc, char **argv) -{ - PyStatus status = _PyRuntime_Initialize(); - if (PyStatus_Exception(status)) { - Py_ExitStatusException(status); - } - - const char *p; - int i, n, sts = 1; - int inspect = 0; - int unbuffered = 0; - char *oldloc = NULL; - wchar_t **argv_copy = NULL; - /* We need a second copies, as Python might modify the first one. */ - wchar_t **argv_copy2 = NULL; - - if (argc > 0) { - argv_copy = PyMem_RawMalloc(sizeof(wchar_t*) * argc); - argv_copy2 = PyMem_RawMalloc(sizeof(wchar_t*) * argc); - if (!argv_copy || !argv_copy2) { - fprintf(stderr, "out of memory\n"); - goto error; - } - } - - PyConfig config; - PyConfig_InitPythonConfig(&config); - config.pathconfig_warnings = 0; /* Suppress errors from getpath.c */ - - if ((p = Py_GETENV("PYTHONINSPECT")) && *p != '\0') - inspect = 1; - if ((p = Py_GETENV("PYTHONUNBUFFERED")) && *p != '\0') - unbuffered = 1; - - if (unbuffered) { - setbuf(stdin, (char *)NULL); - setbuf(stdout, (char *)NULL); - setbuf(stderr, (char *)NULL); - } - - oldloc = _PyMem_RawStrdup(setlocale(LC_ALL, NULL)); - if (!oldloc) { - fprintf(stderr, "out of memory\n"); - goto error; - } - - setlocale(LC_ALL, ""); - for (i = 0; i < argc; i++) { - argv_copy[i] = Py_DecodeLocale(argv[i], NULL); - argv_copy2[i] = argv_copy[i]; - if (!argv_copy[i]) { - fprintf(stderr, "Unable to decode the command line argument #%i\n", - i + 1); - argc = i; - goto error; - } - } - setlocale(LC_ALL, oldloc); - PyMem_RawFree(oldloc); - oldloc = NULL; - -#ifdef MS_WINDOWS - PyInitFrozenExtensions(); -#endif /* MS_WINDOWS */ - if (argc >= 1) - Py_SetProgramName(argv_copy[0]); - - status = Py_InitializeFromConfig(&config); - PyConfig_Clear(&config); - if (PyStatus_Exception(status)) { - Py_ExitStatusException(status); - } - -#ifdef MS_WINDOWS - PyWinFreeze_ExeInit(); -#endif - - if (Py_VerboseFlag) - fprintf(stderr, "Python %s\n%s\n", - Py_GetVersion(), Py_GetCopyright()); - - PySys_SetArgv(argc, argv_copy); - - n = PyImport_ImportFrozenModule("__main__"); - if (n == 0) - Py_FatalError("the __main__ module is not frozen"); - if (n < 0) { - PyErr_Print(); - sts = 1; - } - else - sts = 0; - - if (inspect && isatty((int)fileno(stdin))) - sts = PyRun_AnyFile(stdin, "<stdin>") != 0; - -#ifdef MS_WINDOWS - PyWinFreeze_ExeTerm(); -#endif - if (Py_FinalizeEx() < 0) { - sts = 120; - } - -error: - PyMem_RawFree(argv_copy); - if (argv_copy2) { - for (i = 0; i < argc; i++) - PyMem_RawFree(argv_copy2[i]); - PyMem_RawFree(argv_copy2); - } - PyMem_RawFree(oldloc); - return sts; -} diff --git a/contrib/tools/python3/src/Python/future.c b/contrib/tools/python3/src/Python/future.c deleted file mode 100644 index d465608ca45..00000000000 --- a/contrib/tools/python3/src/Python/future.c +++ /dev/null @@ -1,136 +0,0 @@ -#include "Python.h" -#include "pycore_ast.h" // _PyAST_GetDocString() - -#define UNDEFINED_FUTURE_FEATURE "future feature %.100s is not defined" -#define ERR_LATE_FUTURE \ -"from __future__ imports must occur at the beginning of the file" - -static int -future_check_features(PyFutureFeatures *ff, stmt_ty s, PyObject *filename) -{ - int i; - - assert(s->kind == ImportFrom_kind); - - asdl_alias_seq *names = s->v.ImportFrom.names; - for (i = 0; i < asdl_seq_LEN(names); i++) { - alias_ty name = (alias_ty)asdl_seq_GET(names, i); - const char *feature = PyUnicode_AsUTF8(name->name); - if (!feature) - return 0; - if (strcmp(feature, FUTURE_NESTED_SCOPES) == 0) { - continue; - } else if (strcmp(feature, FUTURE_GENERATORS) == 0) { - continue; - } else if (strcmp(feature, FUTURE_DIVISION) == 0) { - continue; - } else if (strcmp(feature, FUTURE_ABSOLUTE_IMPORT) == 0) { - continue; - } else if (strcmp(feature, FUTURE_WITH_STATEMENT) == 0) { - continue; - } else if (strcmp(feature, FUTURE_PRINT_FUNCTION) == 0) { - continue; - } else if (strcmp(feature, FUTURE_UNICODE_LITERALS) == 0) { - continue; - } else if (strcmp(feature, FUTURE_BARRY_AS_BDFL) == 0) { - ff->ff_features |= CO_FUTURE_BARRY_AS_BDFL; - } else if (strcmp(feature, FUTURE_GENERATOR_STOP) == 0) { - continue; - } else if (strcmp(feature, FUTURE_ANNOTATIONS) == 0) { - ff->ff_features |= CO_FUTURE_ANNOTATIONS; - } else if (strcmp(feature, "braces") == 0) { - PyErr_SetString(PyExc_SyntaxError, - "not a chance"); - PyErr_SyntaxLocationObject(filename, s->lineno, s->col_offset + 1); - return 0; - } else { - PyErr_Format(PyExc_SyntaxError, - UNDEFINED_FUTURE_FEATURE, feature); - PyErr_SyntaxLocationObject(filename, s->lineno, s->col_offset + 1); - return 0; - } - } - return 1; -} - -static int -future_parse(PyFutureFeatures *ff, mod_ty mod, PyObject *filename) -{ - int i, done = 0, prev_line = 0; - - if (!(mod->kind == Module_kind || mod->kind == Interactive_kind)) - return 1; - - if (asdl_seq_LEN(mod->v.Module.body) == 0) - return 1; - - /* A subsequent pass will detect future imports that don't - appear at the beginning of the file. There's one case, - however, that is easier to handle here: A series of imports - joined by semi-colons, where the first import is a future - statement but some subsequent import has the future form - but is preceded by a regular import. - */ - - i = 0; - if (_PyAST_GetDocString(mod->v.Module.body) != NULL) - i++; - - for (; i < asdl_seq_LEN(mod->v.Module.body); i++) { - stmt_ty s = (stmt_ty)asdl_seq_GET(mod->v.Module.body, i); - - if (done && s->lineno > prev_line) - return 1; - prev_line = s->lineno; - - /* The tests below will return from this function unless it is - still possible to find a future statement. The only things - that can precede a future statement are another future - statement and a doc string. - */ - - if (s->kind == ImportFrom_kind) { - identifier modname = s->v.ImportFrom.module; - if (modname && - _PyUnicode_EqualToASCIIString(modname, "__future__")) { - if (done) { - PyErr_SetString(PyExc_SyntaxError, - ERR_LATE_FUTURE); - PyErr_SyntaxLocationObject(filename, s->lineno, s->col_offset); - return 0; - } - if (!future_check_features(ff, s, filename)) - return 0; - ff->ff_lineno = s->lineno; - } - else { - done = 1; - } - } - else { - done = 1; - } - } - return 1; -} - - -PyFutureFeatures * -_PyFuture_FromAST(mod_ty mod, PyObject *filename) -{ - PyFutureFeatures *ff; - - ff = (PyFutureFeatures *)PyObject_Malloc(sizeof(PyFutureFeatures)); - if (ff == NULL) { - PyErr_NoMemory(); - return NULL; - } - ff->ff_features = 0; - ff->ff_lineno = -1; - - if (!future_parse(ff, mod, filename)) { - PyObject_Free(ff); - return NULL; - } - return ff; -} diff --git a/contrib/tools/python3/src/Python/getargs.c b/contrib/tools/python3/src/Python/getargs.c deleted file mode 100644 index d5e083509ef..00000000000 --- a/contrib/tools/python3/src/Python/getargs.c +++ /dev/null @@ -1,2792 +0,0 @@ - -/* New getargs implementation */ - -#include "Python.h" -#include "pycore_tuple.h" // _PyTuple_ITEMS() - -#include <ctype.h> -#include <float.h> - - -#ifdef __cplusplus -extern "C" { -#endif -int PyArg_Parse(PyObject *, const char *, ...); -int PyArg_ParseTuple(PyObject *, const char *, ...); -int PyArg_VaParse(PyObject *, const char *, va_list); - -int PyArg_ParseTupleAndKeywords(PyObject *, PyObject *, - const char *, char **, ...); -int PyArg_VaParseTupleAndKeywords(PyObject *, PyObject *, - const char *, char **, va_list); - -int _PyArg_ParseTupleAndKeywordsFast(PyObject *, PyObject *, - struct _PyArg_Parser *, ...); -int _PyArg_VaParseTupleAndKeywordsFast(PyObject *, PyObject *, - struct _PyArg_Parser *, va_list); - -#ifdef HAVE_DECLSPEC_DLL -/* Export functions */ -PyAPI_FUNC(int) _PyArg_Parse_SizeT(PyObject *, const char *, ...); -PyAPI_FUNC(int) _PyArg_ParseStack_SizeT(PyObject *const *args, Py_ssize_t nargs, - const char *format, ...); -PyAPI_FUNC(int) _PyArg_ParseStackAndKeywords_SizeT(PyObject *const *args, Py_ssize_t nargs, - PyObject *kwnames, - struct _PyArg_Parser *parser, ...); -PyAPI_FUNC(int) _PyArg_ParseTuple_SizeT(PyObject *, const char *, ...); -PyAPI_FUNC(int) _PyArg_ParseTupleAndKeywords_SizeT(PyObject *, PyObject *, - const char *, char **, ...); -PyAPI_FUNC(PyObject *) _Py_BuildValue_SizeT(const char *, ...); -PyAPI_FUNC(int) _PyArg_VaParse_SizeT(PyObject *, const char *, va_list); -PyAPI_FUNC(int) _PyArg_VaParseTupleAndKeywords_SizeT(PyObject *, PyObject *, - const char *, char **, va_list); - -PyAPI_FUNC(int) _PyArg_ParseTupleAndKeywordsFast_SizeT(PyObject *, PyObject *, - struct _PyArg_Parser *, ...); -PyAPI_FUNC(int) _PyArg_VaParseTupleAndKeywordsFast_SizeT(PyObject *, PyObject *, - struct _PyArg_Parser *, va_list); -#endif - -#define FLAG_COMPAT 1 -#define FLAG_SIZE_T 2 - -typedef int (*destr_t)(PyObject *, void *); - - -/* Keep track of "objects" that have been allocated or initialized and - which will need to be deallocated or cleaned up somehow if overall - parsing fails. -*/ -typedef struct { - void *item; - destr_t destructor; -} freelistentry_t; - -typedef struct { - freelistentry_t *entries; - int first_available; - int entries_malloced; -} freelist_t; - -#define STATIC_FREELIST_ENTRIES 8 - -/* Forward */ -static int vgetargs1_impl(PyObject *args, PyObject *const *stack, Py_ssize_t nargs, - const char *format, va_list *p_va, int flags); -static int vgetargs1(PyObject *, const char *, va_list *, int); -static void seterror(Py_ssize_t, const char *, int *, const char *, const char *); -static const char *convertitem(PyObject *, const char **, va_list *, int, int *, - char *, size_t, freelist_t *); -static const char *converttuple(PyObject *, const char **, va_list *, int, - int *, char *, size_t, int, freelist_t *); -static const char *convertsimple(PyObject *, const char **, va_list *, int, - char *, size_t, freelist_t *); -static Py_ssize_t convertbuffer(PyObject *, const void **p, const char **); -static int getbuffer(PyObject *, Py_buffer *, const char**); - -static int vgetargskeywords(PyObject *, PyObject *, - const char *, char **, va_list *, int); -static int vgetargskeywordsfast(PyObject *, PyObject *, - struct _PyArg_Parser *, va_list *, int); -static int vgetargskeywordsfast_impl(PyObject *const *args, Py_ssize_t nargs, - PyObject *keywords, PyObject *kwnames, - struct _PyArg_Parser *parser, - va_list *p_va, int flags); -static const char *skipitem(const char **, va_list *, int); - -int -PyArg_Parse(PyObject *args, const char *format, ...) -{ - int retval; - va_list va; - - va_start(va, format); - retval = vgetargs1(args, format, &va, FLAG_COMPAT); - va_end(va); - return retval; -} - -PyAPI_FUNC(int) -_PyArg_Parse_SizeT(PyObject *args, const char *format, ...) -{ - int retval; - va_list va; - - va_start(va, format); - retval = vgetargs1(args, format, &va, FLAG_COMPAT|FLAG_SIZE_T); - va_end(va); - return retval; -} - - -int -PyArg_ParseTuple(PyObject *args, const char *format, ...) -{ - int retval; - va_list va; - - va_start(va, format); - retval = vgetargs1(args, format, &va, 0); - va_end(va); - return retval; -} - -PyAPI_FUNC(int) -_PyArg_ParseTuple_SizeT(PyObject *args, const char *format, ...) -{ - int retval; - va_list va; - - va_start(va, format); - retval = vgetargs1(args, format, &va, FLAG_SIZE_T); - va_end(va); - return retval; -} - - -int -_PyArg_ParseStack(PyObject *const *args, Py_ssize_t nargs, const char *format, ...) -{ - int retval; - va_list va; - - va_start(va, format); - retval = vgetargs1_impl(NULL, args, nargs, format, &va, 0); - va_end(va); - return retval; -} - -PyAPI_FUNC(int) -_PyArg_ParseStack_SizeT(PyObject *const *args, Py_ssize_t nargs, const char *format, ...) -{ - int retval; - va_list va; - - va_start(va, format); - retval = vgetargs1_impl(NULL, args, nargs, format, &va, FLAG_SIZE_T); - va_end(va); - return retval; -} - - -int -PyArg_VaParse(PyObject *args, const char *format, va_list va) -{ - va_list lva; - int retval; - - va_copy(lva, va); - - retval = vgetargs1(args, format, &lva, 0); - va_end(lva); - return retval; -} - -PyAPI_FUNC(int) -_PyArg_VaParse_SizeT(PyObject *args, const char *format, va_list va) -{ - va_list lva; - int retval; - - va_copy(lva, va); - - retval = vgetargs1(args, format, &lva, FLAG_SIZE_T); - va_end(lva); - return retval; -} - - -/* Handle cleanup of allocated memory in case of exception */ - -static int -cleanup_ptr(PyObject *self, void *ptr) -{ - if (ptr) { - PyMem_Free(ptr); - } - return 0; -} - -static int -cleanup_buffer(PyObject *self, void *ptr) -{ - Py_buffer *buf = (Py_buffer *)ptr; - if (buf) { - PyBuffer_Release(buf); - } - return 0; -} - -static int -addcleanup(void *ptr, freelist_t *freelist, destr_t destructor) -{ - int index; - - index = freelist->first_available; - freelist->first_available += 1; - - freelist->entries[index].item = ptr; - freelist->entries[index].destructor = destructor; - - return 0; -} - -static int -cleanreturn(int retval, freelist_t *freelist) -{ - int index; - - if (retval == 0) { - /* A failure occurred, therefore execute all of the cleanup - functions. - */ - for (index = 0; index < freelist->first_available; ++index) { - freelist->entries[index].destructor(NULL, - freelist->entries[index].item); - } - } - if (freelist->entries_malloced) - PyMem_Free(freelist->entries); - return retval; -} - - -static int -vgetargs1_impl(PyObject *compat_args, PyObject *const *stack, Py_ssize_t nargs, const char *format, - va_list *p_va, int flags) -{ - char msgbuf[256]; - int levels[32]; - const char *fname = NULL; - const char *message = NULL; - int min = -1; - int max = 0; - int level = 0; - int endfmt = 0; - const char *formatsave = format; - Py_ssize_t i; - const char *msg; - int compat = flags & FLAG_COMPAT; - freelistentry_t static_entries[STATIC_FREELIST_ENTRIES]; - freelist_t freelist; - - assert(nargs == 0 || stack != NULL); - - freelist.entries = static_entries; - freelist.first_available = 0; - freelist.entries_malloced = 0; - - flags = flags & ~FLAG_COMPAT; - - while (endfmt == 0) { - int c = *format++; - switch (c) { - case '(': - if (level == 0) - max++; - level++; - if (level >= 30) - Py_FatalError("too many tuple nesting levels " - "in argument format string"); - break; - case ')': - if (level == 0) - Py_FatalError("excess ')' in getargs format"); - else - level--; - break; - case '\0': - endfmt = 1; - break; - case ':': - fname = format; - endfmt = 1; - break; - case ';': - message = format; - endfmt = 1; - break; - case '|': - if (level == 0) - min = max; - break; - default: - if (level == 0) { - if (Py_ISALPHA(c)) - if (c != 'e') /* skip encoded */ - max++; - } - break; - } - } - - if (level != 0) - Py_FatalError(/* '(' */ "missing ')' in getargs format"); - - if (min < 0) - min = max; - - format = formatsave; - - if (max > STATIC_FREELIST_ENTRIES) { - freelist.entries = PyMem_NEW(freelistentry_t, max); - if (freelist.entries == NULL) { - PyErr_NoMemory(); - return 0; - } - freelist.entries_malloced = 1; - } - - if (compat) { - if (max == 0) { - if (compat_args == NULL) - return 1; - PyErr_Format(PyExc_TypeError, - "%.200s%s takes no arguments", - fname==NULL ? "function" : fname, - fname==NULL ? "" : "()"); - return cleanreturn(0, &freelist); - } - else if (min == 1 && max == 1) { - if (compat_args == NULL) { - PyErr_Format(PyExc_TypeError, - "%.200s%s takes at least one argument", - fname==NULL ? "function" : fname, - fname==NULL ? "" : "()"); - return cleanreturn(0, &freelist); - } - msg = convertitem(compat_args, &format, p_va, flags, levels, - msgbuf, sizeof(msgbuf), &freelist); - if (msg == NULL) - return cleanreturn(1, &freelist); - seterror(levels[0], msg, levels+1, fname, message); - return cleanreturn(0, &freelist); - } - else { - PyErr_SetString(PyExc_SystemError, - "old style getargs format uses new features"); - return cleanreturn(0, &freelist); - } - } - - if (nargs < min || max < nargs) { - if (message == NULL) - PyErr_Format(PyExc_TypeError, - "%.150s%s takes %s %d argument%s (%zd given)", - fname==NULL ? "function" : fname, - fname==NULL ? "" : "()", - min==max ? "exactly" - : nargs < min ? "at least" : "at most", - nargs < min ? min : max, - (nargs < min ? min : max) == 1 ? "" : "s", - nargs); - else - PyErr_SetString(PyExc_TypeError, message); - return cleanreturn(0, &freelist); - } - - for (i = 0; i < nargs; i++) { - if (*format == '|') - format++; - msg = convertitem(stack[i], &format, p_va, - flags, levels, msgbuf, - sizeof(msgbuf), &freelist); - if (msg) { - seterror(i+1, msg, levels, fname, message); - return cleanreturn(0, &freelist); - } - } - - if (*format != '\0' && !Py_ISALPHA(*format) && - *format != '(' && - *format != '|' && *format != ':' && *format != ';') { - PyErr_Format(PyExc_SystemError, - "bad format string: %.200s", formatsave); - return cleanreturn(0, &freelist); - } - - return cleanreturn(1, &freelist); -} - -static int -vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags) -{ - PyObject **stack; - Py_ssize_t nargs; - - if (!(flags & FLAG_COMPAT)) { - assert(args != NULL); - - if (!PyTuple_Check(args)) { - PyErr_SetString(PyExc_SystemError, - "new style getargs format but argument is not a tuple"); - return 0; - } - - stack = _PyTuple_ITEMS(args); - nargs = PyTuple_GET_SIZE(args); - } - else { - stack = NULL; - nargs = 0; - } - - return vgetargs1_impl(args, stack, nargs, format, p_va, flags); -} - - -static void -seterror(Py_ssize_t iarg, const char *msg, int *levels, const char *fname, - const char *message) -{ - char buf[512]; - int i; - char *p = buf; - - if (PyErr_Occurred()) - return; - else if (message == NULL) { - if (fname != NULL) { - PyOS_snprintf(p, sizeof(buf), "%.200s() ", fname); - p += strlen(p); - } - if (iarg != 0) { - PyOS_snprintf(p, sizeof(buf) - (p - buf), - "argument %zd", iarg); - i = 0; - p += strlen(p); - while (i < 32 && levels[i] > 0 && (int)(p-buf) < 220) { - PyOS_snprintf(p, sizeof(buf) - (p - buf), - ", item %d", levels[i]-1); - p += strlen(p); - i++; - } - } - else { - PyOS_snprintf(p, sizeof(buf) - (p - buf), "argument"); - p += strlen(p); - } - PyOS_snprintf(p, sizeof(buf) - (p - buf), " %.256s", msg); - message = buf; - } - if (msg[0] == '(') { - PyErr_SetString(PyExc_SystemError, message); - } - else { - PyErr_SetString(PyExc_TypeError, message); - } -} - - -/* Convert a tuple argument. - On entry, *p_format points to the character _after_ the opening '('. - On successful exit, *p_format points to the closing ')'. - If successful: - *p_format and *p_va are updated, - *levels and *msgbuf are untouched, - and NULL is returned. - If the argument is invalid: - *p_format is unchanged, - *p_va is undefined, - *levels is a 0-terminated list of item numbers, - *msgbuf contains an error message, whose format is: - "must be <typename1>, not <typename2>", where: - <typename1> is the name of the expected type, and - <typename2> is the name of the actual type, - and msgbuf is returned. -*/ - -static const char * -converttuple(PyObject *arg, const char **p_format, va_list *p_va, int flags, - int *levels, char *msgbuf, size_t bufsize, int toplevel, - freelist_t *freelist) -{ - int level = 0; - int n = 0; - const char *format = *p_format; - int i; - Py_ssize_t len; - - for (;;) { - int c = *format++; - if (c == '(') { - if (level == 0) - n++; - level++; - } - else if (c == ')') { - if (level == 0) - break; - level--; - } - else if (c == ':' || c == ';' || c == '\0') - break; - else if (level == 0 && Py_ISALPHA(c)) - n++; - } - - if (!PySequence_Check(arg) || PyBytes_Check(arg)) { - levels[0] = 0; - PyOS_snprintf(msgbuf, bufsize, - toplevel ? "expected %d arguments, not %.50s" : - "must be %d-item sequence, not %.50s", - n, - arg == Py_None ? "None" : Py_TYPE(arg)->tp_name); - return msgbuf; - } - - len = PySequence_Size(arg); - if (len != n) { - levels[0] = 0; - if (toplevel) { - PyOS_snprintf(msgbuf, bufsize, - "expected %d argument%s, not %zd", - n, - n == 1 ? "" : "s", - len); - } - else { - PyOS_snprintf(msgbuf, bufsize, - "must be sequence of length %d, not %zd", - n, len); - } - return msgbuf; - } - - format = *p_format; - for (i = 0; i < n; i++) { - const char *msg; - PyObject *item; - item = PySequence_GetItem(arg, i); - if (item == NULL) { - PyErr_Clear(); - levels[0] = i+1; - levels[1] = 0; - strncpy(msgbuf, "is not retrievable", bufsize); - return msgbuf; - } - msg = convertitem(item, &format, p_va, flags, levels+1, - msgbuf, bufsize, freelist); - /* PySequence_GetItem calls tp->sq_item, which INCREFs */ - Py_XDECREF(item); - if (msg != NULL) { - levels[0] = i+1; - return msg; - } - } - - *p_format = format; - return NULL; -} - - -/* Convert a single item. */ - -static const char * -convertitem(PyObject *arg, const char **p_format, va_list *p_va, int flags, - int *levels, char *msgbuf, size_t bufsize, freelist_t *freelist) -{ - const char *msg; - const char *format = *p_format; - - if (*format == '(' /* ')' */) { - format++; - msg = converttuple(arg, &format, p_va, flags, levels, msgbuf, - bufsize, 0, freelist); - if (msg == NULL) - format++; - } - else { - msg = convertsimple(arg, &format, p_va, flags, - msgbuf, bufsize, freelist); - if (msg != NULL) - levels[0] = 0; - } - if (msg == NULL) - *p_format = format; - return msg; -} - - - -/* Format an error message generated by convertsimple(). - displayname must be UTF-8 encoded. -*/ - -void -_PyArg_BadArgument(const char *fname, const char *displayname, - const char *expected, PyObject *arg) -{ - PyErr_Format(PyExc_TypeError, - "%.200s() %.200s must be %.50s, not %.50s", - fname, displayname, expected, - arg == Py_None ? "None" : Py_TYPE(arg)->tp_name); -} - -static const char * -converterr(const char *expected, PyObject *arg, char *msgbuf, size_t bufsize) -{ - assert(expected != NULL); - assert(arg != NULL); - if (expected[0] == '(') { - PyOS_snprintf(msgbuf, bufsize, - "%.100s", expected); - } - else { - PyOS_snprintf(msgbuf, bufsize, - "must be %.50s, not %.50s", expected, - arg == Py_None ? "None" : Py_TYPE(arg)->tp_name); - } - return msgbuf; -} - -#define CONV_UNICODE "(unicode conversion error)" - -/* Convert a non-tuple argument. Return NULL if conversion went OK, - or a string with a message describing the failure. The message is - formatted as "must be <desired type>, not <actual type>". - When failing, an exception may or may not have been raised. - Don't call if a tuple is expected. - - When you add new format codes, please don't forget poor skipitem() below. -*/ - -static const char * -convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, - char *msgbuf, size_t bufsize, freelist_t *freelist) -{ -#define RETURN_ERR_OCCURRED return msgbuf - /* For # codes */ -#define REQUIRE_PY_SSIZE_T_CLEAN \ - if (!(flags & FLAG_SIZE_T)) { \ - PyErr_SetString(PyExc_SystemError, \ - "PY_SSIZE_T_CLEAN macro must be defined for '#' formats"); \ - RETURN_ERR_OCCURRED; \ - } - - const char *format = *p_format; - char c = *format++; - const char *sarg; - - switch (c) { - - case 'b': { /* unsigned byte -- very short int */ - char *p = va_arg(*p_va, char *); - long ival = PyLong_AsLong(arg); - if (ival == -1 && PyErr_Occurred()) - RETURN_ERR_OCCURRED; - else if (ival < 0) { - PyErr_SetString(PyExc_OverflowError, - "unsigned byte integer is less than minimum"); - RETURN_ERR_OCCURRED; - } - else if (ival > UCHAR_MAX) { - PyErr_SetString(PyExc_OverflowError, - "unsigned byte integer is greater than maximum"); - RETURN_ERR_OCCURRED; - } - else - *p = (unsigned char) ival; - break; - } - - case 'B': {/* byte sized bitfield - both signed and unsigned - values allowed */ - char *p = va_arg(*p_va, char *); - unsigned long ival = PyLong_AsUnsignedLongMask(arg); - if (ival == (unsigned long)-1 && PyErr_Occurred()) - RETURN_ERR_OCCURRED; - else - *p = (unsigned char) ival; - break; - } - - case 'h': {/* signed short int */ - short *p = va_arg(*p_va, short *); - long ival = PyLong_AsLong(arg); - if (ival == -1 && PyErr_Occurred()) - RETURN_ERR_OCCURRED; - else if (ival < SHRT_MIN) { - PyErr_SetString(PyExc_OverflowError, - "signed short integer is less than minimum"); - RETURN_ERR_OCCURRED; - } - else if (ival > SHRT_MAX) { - PyErr_SetString(PyExc_OverflowError, - "signed short integer is greater than maximum"); - RETURN_ERR_OCCURRED; - } - else - *p = (short) ival; - break; - } - - case 'H': { /* short int sized bitfield, both signed and - unsigned allowed */ - unsigned short *p = va_arg(*p_va, unsigned short *); - unsigned long ival = PyLong_AsUnsignedLongMask(arg); - if (ival == (unsigned long)-1 && PyErr_Occurred()) - RETURN_ERR_OCCURRED; - else - *p = (unsigned short) ival; - break; - } - - case 'i': {/* signed int */ - int *p = va_arg(*p_va, int *); - long ival = PyLong_AsLong(arg); - if (ival == -1 && PyErr_Occurred()) - RETURN_ERR_OCCURRED; - else if (ival > INT_MAX) { - PyErr_SetString(PyExc_OverflowError, - "signed integer is greater than maximum"); - RETURN_ERR_OCCURRED; - } - else if (ival < INT_MIN) { - PyErr_SetString(PyExc_OverflowError, - "signed integer is less than minimum"); - RETURN_ERR_OCCURRED; - } - else - *p = ival; - break; - } - - case 'I': { /* int sized bitfield, both signed and - unsigned allowed */ - unsigned int *p = va_arg(*p_va, unsigned int *); - unsigned long ival = PyLong_AsUnsignedLongMask(arg); - if (ival == (unsigned long)-1 && PyErr_Occurred()) - RETURN_ERR_OCCURRED; - else - *p = (unsigned int) ival; - break; - } - - case 'n': /* Py_ssize_t */ - { - PyObject *iobj; - Py_ssize_t *p = va_arg(*p_va, Py_ssize_t *); - Py_ssize_t ival = -1; - iobj = _PyNumber_Index(arg); - if (iobj != NULL) { - ival = PyLong_AsSsize_t(iobj); - Py_DECREF(iobj); - } - if (ival == -1 && PyErr_Occurred()) - RETURN_ERR_OCCURRED; - *p = ival; - break; - } - case 'l': {/* long int */ - long *p = va_arg(*p_va, long *); - long ival = PyLong_AsLong(arg); - if (ival == -1 && PyErr_Occurred()) - RETURN_ERR_OCCURRED; - else - *p = ival; - break; - } - - case 'k': { /* long sized bitfield */ - unsigned long *p = va_arg(*p_va, unsigned long *); - unsigned long ival; - if (PyLong_Check(arg)) - ival = PyLong_AsUnsignedLongMask(arg); - else - return converterr("int", arg, msgbuf, bufsize); - *p = ival; - break; - } - - case 'L': {/* long long */ - long long *p = va_arg( *p_va, long long * ); - long long ival = PyLong_AsLongLong(arg); - if (ival == (long long)-1 && PyErr_Occurred()) - RETURN_ERR_OCCURRED; - else - *p = ival; - break; - } - - case 'K': { /* long long sized bitfield */ - unsigned long long *p = va_arg(*p_va, unsigned long long *); - unsigned long long ival; - if (PyLong_Check(arg)) - ival = PyLong_AsUnsignedLongLongMask(arg); - else - return converterr("int", arg, msgbuf, bufsize); - *p = ival; - break; - } - - case 'f': {/* float */ - float *p = va_arg(*p_va, float *); - double dval = PyFloat_AsDouble(arg); - if (dval == -1.0 && PyErr_Occurred()) - RETURN_ERR_OCCURRED; - else - *p = (float) dval; - break; - } - - case 'd': {/* double */ - double *p = va_arg(*p_va, double *); - double dval = PyFloat_AsDouble(arg); - if (dval == -1.0 && PyErr_Occurred()) - RETURN_ERR_OCCURRED; - else - *p = dval; - break; - } - - case 'D': {/* complex double */ - Py_complex *p = va_arg(*p_va, Py_complex *); - Py_complex cval; - cval = PyComplex_AsCComplex(arg); - if (PyErr_Occurred()) - RETURN_ERR_OCCURRED; - else - *p = cval; - break; - } - - case 'c': {/* char */ - char *p = va_arg(*p_va, char *); - if (PyBytes_Check(arg) && PyBytes_Size(arg) == 1) - *p = PyBytes_AS_STRING(arg)[0]; - else if (PyByteArray_Check(arg) && PyByteArray_Size(arg) == 1) - *p = PyByteArray_AS_STRING(arg)[0]; - else - return converterr("a byte string of length 1", arg, msgbuf, bufsize); - break; - } - - case 'C': {/* unicode char */ - int *p = va_arg(*p_va, int *); - int kind; - const void *data; - - if (!PyUnicode_Check(arg)) - return converterr("a unicode character", arg, msgbuf, bufsize); - - if (PyUnicode_READY(arg)) - RETURN_ERR_OCCURRED; - - if (PyUnicode_GET_LENGTH(arg) != 1) - return converterr("a unicode character", arg, msgbuf, bufsize); - - kind = PyUnicode_KIND(arg); - data = PyUnicode_DATA(arg); - *p = PyUnicode_READ(kind, data, 0); - break; - } - - case 'p': {/* boolean *p*redicate */ - int *p = va_arg(*p_va, int *); - int val = PyObject_IsTrue(arg); - if (val > 0) - *p = 1; - else if (val == 0) - *p = 0; - else - RETURN_ERR_OCCURRED; - break; - } - - /* XXX WAAAAH! 's', 'y', 'z', 'u', 'Z', 'e', 'w' codes all - need to be cleaned up! */ - - case 'y': {/* any bytes-like object */ - void **p = (void **)va_arg(*p_va, char **); - const char *buf; - Py_ssize_t count; - if (*format == '*') { - if (getbuffer(arg, (Py_buffer*)p, &buf) < 0) - return converterr(buf, arg, msgbuf, bufsize); - format++; - if (addcleanup(p, freelist, cleanup_buffer)) { - return converterr( - "(cleanup problem)", - arg, msgbuf, bufsize); - } - break; - } - count = convertbuffer(arg, (const void **)p, &buf); - if (count < 0) - return converterr(buf, arg, msgbuf, bufsize); - if (*format == '#') { - REQUIRE_PY_SSIZE_T_CLEAN; - Py_ssize_t *psize = va_arg(*p_va, Py_ssize_t*); - *psize = count; - format++; - } else { - if (strlen(*p) != (size_t)count) { - PyErr_SetString(PyExc_ValueError, "embedded null byte"); - RETURN_ERR_OCCURRED; - } - } - break; - } - - case 's': /* text string or bytes-like object */ - case 'z': /* text string, bytes-like object or None */ - { - if (*format == '*') { - /* "s*" or "z*" */ - Py_buffer *p = (Py_buffer *)va_arg(*p_va, Py_buffer *); - - if (c == 'z' && arg == Py_None) - PyBuffer_FillInfo(p, NULL, NULL, 0, 1, 0); - else if (PyUnicode_Check(arg)) { - Py_ssize_t len; - sarg = PyUnicode_AsUTF8AndSize(arg, &len); - if (sarg == NULL) - return converterr(CONV_UNICODE, - arg, msgbuf, bufsize); - PyBuffer_FillInfo(p, arg, (void *)sarg, len, 1, 0); - } - else { /* any bytes-like object */ - const char *buf; - if (getbuffer(arg, p, &buf) < 0) - return converterr(buf, arg, msgbuf, bufsize); - } - if (addcleanup(p, freelist, cleanup_buffer)) { - return converterr( - "(cleanup problem)", - arg, msgbuf, bufsize); - } - format++; - } else if (*format == '#') { /* a string or read-only bytes-like object */ - /* "s#" or "z#" */ - const void **p = (const void **)va_arg(*p_va, const char **); - REQUIRE_PY_SSIZE_T_CLEAN; - Py_ssize_t *psize = va_arg(*p_va, Py_ssize_t*); - - if (c == 'z' && arg == Py_None) { - *p = NULL; - *psize = 0; - } - else if (PyUnicode_Check(arg)) { - Py_ssize_t len; - sarg = PyUnicode_AsUTF8AndSize(arg, &len); - if (sarg == NULL) - return converterr(CONV_UNICODE, - arg, msgbuf, bufsize); - *p = sarg; - *psize = len; - } - else { /* read-only bytes-like object */ - /* XXX Really? */ - const char *buf; - Py_ssize_t count = convertbuffer(arg, p, &buf); - if (count < 0) - return converterr(buf, arg, msgbuf, bufsize); - *psize = count; - } - format++; - } else { - /* "s" or "z" */ - const char **p = va_arg(*p_va, const char **); - Py_ssize_t len; - sarg = NULL; - - if (c == 'z' && arg == Py_None) - *p = NULL; - else if (PyUnicode_Check(arg)) { - sarg = PyUnicode_AsUTF8AndSize(arg, &len); - if (sarg == NULL) - return converterr(CONV_UNICODE, - arg, msgbuf, bufsize); - if (strlen(sarg) != (size_t)len) { - PyErr_SetString(PyExc_ValueError, "embedded null character"); - RETURN_ERR_OCCURRED; - } - *p = sarg; - } - else - return converterr(c == 'z' ? "str or None" : "str", - arg, msgbuf, bufsize); - } - break; - } - - case 'u': /* raw unicode buffer (Py_UNICODE *) */ - case 'Z': /* raw unicode buffer or None */ - { - if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, - "getargs: The '%c' format is deprecated. Use 'U' instead.", c)) { - return NULL; - } -_Py_COMP_DIAG_PUSH -_Py_COMP_DIAG_IGNORE_DEPR_DECLS - Py_UNICODE **p = va_arg(*p_va, Py_UNICODE **); - - if (*format == '#') { - /* "u#" or "Z#" */ - REQUIRE_PY_SSIZE_T_CLEAN; - Py_ssize_t *psize = va_arg(*p_va, Py_ssize_t*); - - if (c == 'Z' && arg == Py_None) { - *p = NULL; - *psize = 0; - } - else if (PyUnicode_Check(arg)) { - Py_ssize_t len; - *p = PyUnicode_AsUnicodeAndSize(arg, &len); - if (*p == NULL) - RETURN_ERR_OCCURRED; - *psize = len; - } - else - return converterr(c == 'Z' ? "str or None" : "str", - arg, msgbuf, bufsize); - format++; - } else { - /* "u" or "Z" */ - if (c == 'Z' && arg == Py_None) - *p = NULL; - else if (PyUnicode_Check(arg)) { - Py_ssize_t len; - *p = PyUnicode_AsUnicodeAndSize(arg, &len); - if (*p == NULL) - RETURN_ERR_OCCURRED; - if (wcslen(*p) != (size_t)len) { - PyErr_SetString(PyExc_ValueError, "embedded null character"); - RETURN_ERR_OCCURRED; - } - } else - return converterr(c == 'Z' ? "str or None" : "str", - arg, msgbuf, bufsize); - } - break; -_Py_COMP_DIAG_POP - } - - case 'e': {/* encoded string */ - char **buffer; - const char *encoding; - PyObject *s; - int recode_strings; - Py_ssize_t size; - const char *ptr; - - /* Get 'e' parameter: the encoding name */ - encoding = (const char *)va_arg(*p_va, const char *); - if (encoding == NULL) - encoding = PyUnicode_GetDefaultEncoding(); - - /* Get output buffer parameter: - 's' (recode all objects via Unicode) or - 't' (only recode non-string objects) - */ - if (*format == 's') - recode_strings = 1; - else if (*format == 't') - recode_strings = 0; - else - return converterr( - "(unknown parser marker combination)", - arg, msgbuf, bufsize); - buffer = (char **)va_arg(*p_va, char **); - format++; - if (buffer == NULL) - return converterr("(buffer is NULL)", - arg, msgbuf, bufsize); - - /* Encode object */ - if (!recode_strings && - (PyBytes_Check(arg) || PyByteArray_Check(arg))) { - s = arg; - Py_INCREF(s); - if (PyBytes_Check(arg)) { - size = PyBytes_GET_SIZE(s); - ptr = PyBytes_AS_STRING(s); - } - else { - size = PyByteArray_GET_SIZE(s); - ptr = PyByteArray_AS_STRING(s); - } - } - else if (PyUnicode_Check(arg)) { - /* Encode object; use default error handling */ - s = PyUnicode_AsEncodedString(arg, - encoding, - NULL); - if (s == NULL) - return converterr("(encoding failed)", - arg, msgbuf, bufsize); - assert(PyBytes_Check(s)); - size = PyBytes_GET_SIZE(s); - ptr = PyBytes_AS_STRING(s); - if (ptr == NULL) - ptr = ""; - } - else { - return converterr( - recode_strings ? "str" : "str, bytes or bytearray", - arg, msgbuf, bufsize); - } - - /* Write output; output is guaranteed to be 0-terminated */ - if (*format == '#') { - /* Using buffer length parameter '#': - - - if *buffer is NULL, a new buffer of the - needed size is allocated and the data - copied into it; *buffer is updated to point - to the new buffer; the caller is - responsible for PyMem_Free()ing it after - usage - - - if *buffer is not NULL, the data is - copied to *buffer; *buffer_len has to be - set to the size of the buffer on input; - buffer overflow is signalled with an error; - buffer has to provide enough room for the - encoded string plus the trailing 0-byte - - - in both cases, *buffer_len is updated to - the size of the buffer /excluding/ the - trailing 0-byte - - */ - REQUIRE_PY_SSIZE_T_CLEAN; - Py_ssize_t *psize = va_arg(*p_va, Py_ssize_t*); - - format++; - if (psize == NULL) { - Py_DECREF(s); - return converterr( - "(buffer_len is NULL)", - arg, msgbuf, bufsize); - } - if (*buffer == NULL) { - *buffer = PyMem_NEW(char, size + 1); - if (*buffer == NULL) { - Py_DECREF(s); - PyErr_NoMemory(); - RETURN_ERR_OCCURRED; - } - if (addcleanup(*buffer, freelist, cleanup_ptr)) { - Py_DECREF(s); - return converterr( - "(cleanup problem)", - arg, msgbuf, bufsize); - } - } else { - if (size + 1 > *psize) { - Py_DECREF(s); - PyErr_Format(PyExc_ValueError, - "encoded string too long " - "(%zd, maximum length %zd)", - (Py_ssize_t)size, (Py_ssize_t)(*psize - 1)); - RETURN_ERR_OCCURRED; - } - } - memcpy(*buffer, ptr, size+1); - - *psize = size; - } - else { - /* Using a 0-terminated buffer: - - - the encoded string has to be 0-terminated - for this variant to work; if it is not, an - error raised - - - a new buffer of the needed size is - allocated and the data copied into it; - *buffer is updated to point to the new - buffer; the caller is responsible for - PyMem_Free()ing it after usage - - */ - if ((Py_ssize_t)strlen(ptr) != size) { - Py_DECREF(s); - return converterr( - "encoded string without null bytes", - arg, msgbuf, bufsize); - } - *buffer = PyMem_NEW(char, size + 1); - if (*buffer == NULL) { - Py_DECREF(s); - PyErr_NoMemory(); - RETURN_ERR_OCCURRED; - } - if (addcleanup(*buffer, freelist, cleanup_ptr)) { - Py_DECREF(s); - return converterr("(cleanup problem)", - arg, msgbuf, bufsize); - } - memcpy(*buffer, ptr, size+1); - } - Py_DECREF(s); - break; - } - - case 'S': { /* PyBytes object */ - PyObject **p = va_arg(*p_va, PyObject **); - if (PyBytes_Check(arg)) - *p = arg; - else - return converterr("bytes", arg, msgbuf, bufsize); - break; - } - - case 'Y': { /* PyByteArray object */ - PyObject **p = va_arg(*p_va, PyObject **); - if (PyByteArray_Check(arg)) - *p = arg; - else - return converterr("bytearray", arg, msgbuf, bufsize); - break; - } - - case 'U': { /* PyUnicode object */ - PyObject **p = va_arg(*p_va, PyObject **); - if (PyUnicode_Check(arg)) { - if (PyUnicode_READY(arg) == -1) - RETURN_ERR_OCCURRED; - *p = arg; - } - else - return converterr("str", arg, msgbuf, bufsize); - break; - } - - case 'O': { /* object */ - PyTypeObject *type; - PyObject **p; - if (*format == '!') { - type = va_arg(*p_va, PyTypeObject*); - p = va_arg(*p_va, PyObject **); - format++; - if (PyType_IsSubtype(Py_TYPE(arg), type)) - *p = arg; - else - return converterr(type->tp_name, arg, msgbuf, bufsize); - - } - else if (*format == '&') { - typedef int (*converter)(PyObject *, void *); - converter convert = va_arg(*p_va, converter); - void *addr = va_arg(*p_va, void *); - int res; - format++; - if (! (res = (*convert)(arg, addr))) - return converterr("(unspecified)", - arg, msgbuf, bufsize); - if (res == Py_CLEANUP_SUPPORTED && - addcleanup(addr, freelist, convert) == -1) - return converterr("(cleanup problem)", - arg, msgbuf, bufsize); - } - else { - p = va_arg(*p_va, PyObject **); - *p = arg; - } - break; - } - - - case 'w': { /* "w*": memory buffer, read-write access */ - void **p = va_arg(*p_va, void **); - - if (*format != '*') - return converterr( - "(invalid use of 'w' format character)", - arg, msgbuf, bufsize); - format++; - - /* Caller is interested in Py_buffer, and the object - supports it directly. */ - if (PyObject_GetBuffer(arg, (Py_buffer*)p, PyBUF_WRITABLE) < 0) { - PyErr_Clear(); - return converterr("read-write bytes-like object", - arg, msgbuf, bufsize); - } - if (!PyBuffer_IsContiguous((Py_buffer*)p, 'C')) { - PyBuffer_Release((Py_buffer*)p); - return converterr("contiguous buffer", arg, msgbuf, bufsize); - } - if (addcleanup(p, freelist, cleanup_buffer)) { - return converterr( - "(cleanup problem)", - arg, msgbuf, bufsize); - } - break; - } - - default: - return converterr("(impossible<bad format char>)", arg, msgbuf, bufsize); - - } - - *p_format = format; - return NULL; - -#undef REQUIRE_PY_SSIZE_T_CLEAN -#undef RETURN_ERR_OCCURRED -} - -static Py_ssize_t -convertbuffer(PyObject *arg, const void **p, const char **errmsg) -{ - PyBufferProcs *pb = Py_TYPE(arg)->tp_as_buffer; - Py_ssize_t count; - Py_buffer view; - - *errmsg = NULL; - *p = NULL; - if (pb != NULL && pb->bf_releasebuffer != NULL) { - *errmsg = "read-only bytes-like object"; - return -1; - } - - if (getbuffer(arg, &view, errmsg) < 0) - return -1; - count = view.len; - *p = view.buf; - PyBuffer_Release(&view); - return count; -} - -static int -getbuffer(PyObject *arg, Py_buffer *view, const char **errmsg) -{ - if (PyObject_GetBuffer(arg, view, PyBUF_SIMPLE) != 0) { - *errmsg = "bytes-like object"; - return -1; - } - if (!PyBuffer_IsContiguous(view, 'C')) { - PyBuffer_Release(view); - *errmsg = "contiguous buffer"; - return -1; - } - return 0; -} - -/* Support for keyword arguments donated by - Geoff Philbrick <[email protected]> */ - -/* Return false (0) for error, else true. */ -int -PyArg_ParseTupleAndKeywords(PyObject *args, - PyObject *keywords, - const char *format, - char **kwlist, ...) -{ - int retval; - va_list va; - - if ((args == NULL || !PyTuple_Check(args)) || - (keywords != NULL && !PyDict_Check(keywords)) || - format == NULL || - kwlist == NULL) - { - PyErr_BadInternalCall(); - return 0; - } - - va_start(va, kwlist); - retval = vgetargskeywords(args, keywords, format, kwlist, &va, 0); - va_end(va); - return retval; -} - -PyAPI_FUNC(int) -_PyArg_ParseTupleAndKeywords_SizeT(PyObject *args, - PyObject *keywords, - const char *format, - char **kwlist, ...) -{ - int retval; - va_list va; - - if ((args == NULL || !PyTuple_Check(args)) || - (keywords != NULL && !PyDict_Check(keywords)) || - format == NULL || - kwlist == NULL) - { - PyErr_BadInternalCall(); - return 0; - } - - va_start(va, kwlist); - retval = vgetargskeywords(args, keywords, format, - kwlist, &va, FLAG_SIZE_T); - va_end(va); - return retval; -} - - -int -PyArg_VaParseTupleAndKeywords(PyObject *args, - PyObject *keywords, - const char *format, - char **kwlist, va_list va) -{ - int retval; - va_list lva; - - if ((args == NULL || !PyTuple_Check(args)) || - (keywords != NULL && !PyDict_Check(keywords)) || - format == NULL || - kwlist == NULL) - { - PyErr_BadInternalCall(); - return 0; - } - - va_copy(lva, va); - - retval = vgetargskeywords(args, keywords, format, kwlist, &lva, 0); - va_end(lva); - return retval; -} - -PyAPI_FUNC(int) -_PyArg_VaParseTupleAndKeywords_SizeT(PyObject *args, - PyObject *keywords, - const char *format, - char **kwlist, va_list va) -{ - int retval; - va_list lva; - - if ((args == NULL || !PyTuple_Check(args)) || - (keywords != NULL && !PyDict_Check(keywords)) || - format == NULL || - kwlist == NULL) - { - PyErr_BadInternalCall(); - return 0; - } - - va_copy(lva, va); - - retval = vgetargskeywords(args, keywords, format, - kwlist, &lva, FLAG_SIZE_T); - va_end(lva); - return retval; -} - -PyAPI_FUNC(int) -_PyArg_ParseTupleAndKeywordsFast(PyObject *args, PyObject *keywords, - struct _PyArg_Parser *parser, ...) -{ - int retval; - va_list va; - - va_start(va, parser); - retval = vgetargskeywordsfast(args, keywords, parser, &va, 0); - va_end(va); - return retval; -} - -PyAPI_FUNC(int) -_PyArg_ParseTupleAndKeywordsFast_SizeT(PyObject *args, PyObject *keywords, - struct _PyArg_Parser *parser, ...) -{ - int retval; - va_list va; - - va_start(va, parser); - retval = vgetargskeywordsfast(args, keywords, parser, &va, FLAG_SIZE_T); - va_end(va); - return retval; -} - -PyAPI_FUNC(int) -_PyArg_ParseStackAndKeywords(PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames, - struct _PyArg_Parser *parser, ...) -{ - int retval; - va_list va; - - va_start(va, parser); - retval = vgetargskeywordsfast_impl(args, nargs, NULL, kwnames, parser, &va, 0); - va_end(va); - return retval; -} - -PyAPI_FUNC(int) -_PyArg_ParseStackAndKeywords_SizeT(PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames, - struct _PyArg_Parser *parser, ...) -{ - int retval; - va_list va; - - va_start(va, parser); - retval = vgetargskeywordsfast_impl(args, nargs, NULL, kwnames, parser, &va, FLAG_SIZE_T); - va_end(va); - return retval; -} - - -PyAPI_FUNC(int) -_PyArg_VaParseTupleAndKeywordsFast(PyObject *args, PyObject *keywords, - struct _PyArg_Parser *parser, va_list va) -{ - int retval; - va_list lva; - - va_copy(lva, va); - - retval = vgetargskeywordsfast(args, keywords, parser, &lva, 0); - va_end(lva); - return retval; -} - -PyAPI_FUNC(int) -_PyArg_VaParseTupleAndKeywordsFast_SizeT(PyObject *args, PyObject *keywords, - struct _PyArg_Parser *parser, va_list va) -{ - int retval; - va_list lva; - - va_copy(lva, va); - - retval = vgetargskeywordsfast(args, keywords, parser, &lva, FLAG_SIZE_T); - va_end(lva); - return retval; -} - -int -PyArg_ValidateKeywordArguments(PyObject *kwargs) -{ - if (!PyDict_Check(kwargs)) { - PyErr_BadInternalCall(); - return 0; - } - if (!_PyDict_HasOnlyStringKeys(kwargs)) { - PyErr_SetString(PyExc_TypeError, - "keywords must be strings"); - return 0; - } - return 1; -} - -#define IS_END_OF_FORMAT(c) (c == '\0' || c == ';' || c == ':') - -static int -vgetargskeywords(PyObject *args, PyObject *kwargs, const char *format, - char **kwlist, va_list *p_va, int flags) -{ - char msgbuf[512]; - int levels[32]; - const char *fname, *msg, *custom_msg; - int min = INT_MAX; - int max = INT_MAX; - int i, pos, len; - int skip = 0; - Py_ssize_t nargs, nkwargs; - PyObject *current_arg; - freelistentry_t static_entries[STATIC_FREELIST_ENTRIES]; - freelist_t freelist; - - freelist.entries = static_entries; - freelist.first_available = 0; - freelist.entries_malloced = 0; - - assert(args != NULL && PyTuple_Check(args)); - assert(kwargs == NULL || PyDict_Check(kwargs)); - assert(format != NULL); - assert(kwlist != NULL); - assert(p_va != NULL); - - /* grab the function name or custom error msg first (mutually exclusive) */ - fname = strchr(format, ':'); - if (fname) { - fname++; - custom_msg = NULL; - } - else { - custom_msg = strchr(format,';'); - if (custom_msg) - custom_msg++; - } - - /* scan kwlist and count the number of positional-only parameters */ - for (pos = 0; kwlist[pos] && !*kwlist[pos]; pos++) { - } - /* scan kwlist and get greatest possible nbr of args */ - for (len = pos; kwlist[len]; len++) { - if (!*kwlist[len]) { - PyErr_SetString(PyExc_SystemError, - "Empty keyword parameter name"); - return cleanreturn(0, &freelist); - } - } - - if (len > STATIC_FREELIST_ENTRIES) { - freelist.entries = PyMem_NEW(freelistentry_t, len); - if (freelist.entries == NULL) { - PyErr_NoMemory(); - return 0; - } - freelist.entries_malloced = 1; - } - - nargs = PyTuple_GET_SIZE(args); - nkwargs = (kwargs == NULL) ? 0 : PyDict_GET_SIZE(kwargs); - if (nargs + nkwargs > len) { - /* Adding "keyword" (when nargs == 0) prevents producing wrong error - messages in some special cases (see bpo-31229). */ - PyErr_Format(PyExc_TypeError, - "%.200s%s takes at most %d %sargument%s (%zd given)", - (fname == NULL) ? "function" : fname, - (fname == NULL) ? "" : "()", - len, - (nargs == 0) ? "keyword " : "", - (len == 1) ? "" : "s", - nargs + nkwargs); - return cleanreturn(0, &freelist); - } - - /* convert tuple args and keyword args in same loop, using kwlist to drive process */ - for (i = 0; i < len; i++) { - if (*format == '|') { - if (min != INT_MAX) { - PyErr_SetString(PyExc_SystemError, - "Invalid format string (| specified twice)"); - return cleanreturn(0, &freelist); - } - - min = i; - format++; - - if (max != INT_MAX) { - PyErr_SetString(PyExc_SystemError, - "Invalid format string ($ before |)"); - return cleanreturn(0, &freelist); - } - } - if (*format == '$') { - if (max != INT_MAX) { - PyErr_SetString(PyExc_SystemError, - "Invalid format string ($ specified twice)"); - return cleanreturn(0, &freelist); - } - - max = i; - format++; - - if (max < pos) { - PyErr_SetString(PyExc_SystemError, - "Empty parameter name after $"); - return cleanreturn(0, &freelist); - } - if (skip) { - /* Now we know the minimal and the maximal numbers of - * positional arguments and can raise an exception with - * informative message (see below). */ - break; - } - if (max < nargs) { - if (max == 0) { - PyErr_Format(PyExc_TypeError, - "%.200s%s takes no positional arguments", - (fname == NULL) ? "function" : fname, - (fname == NULL) ? "" : "()"); - } - else { - PyErr_Format(PyExc_TypeError, - "%.200s%s takes %s %d positional argument%s" - " (%zd given)", - (fname == NULL) ? "function" : fname, - (fname == NULL) ? "" : "()", - (min != INT_MAX) ? "at most" : "exactly", - max, - max == 1 ? "" : "s", - nargs); - } - return cleanreturn(0, &freelist); - } - } - if (IS_END_OF_FORMAT(*format)) { - PyErr_Format(PyExc_SystemError, - "More keyword list entries (%d) than " - "format specifiers (%d)", len, i); - return cleanreturn(0, &freelist); - } - if (!skip) { - if (i < nargs) { - current_arg = PyTuple_GET_ITEM(args, i); - } - else if (nkwargs && i >= pos) { - current_arg = _PyDict_GetItemStringWithError(kwargs, kwlist[i]); - if (current_arg) { - --nkwargs; - } - else if (PyErr_Occurred()) { - return cleanreturn(0, &freelist); - } - } - else { - current_arg = NULL; - } - - if (current_arg) { - msg = convertitem(current_arg, &format, p_va, flags, - levels, msgbuf, sizeof(msgbuf), &freelist); - if (msg) { - seterror(i+1, msg, levels, fname, custom_msg); - return cleanreturn(0, &freelist); - } - continue; - } - - if (i < min) { - if (i < pos) { - assert (min == INT_MAX); - assert (max == INT_MAX); - skip = 1; - /* At that moment we still don't know the minimal and - * the maximal numbers of positional arguments. Raising - * an exception is deferred until we encounter | and $ - * or the end of the format. */ - } - else { - PyErr_Format(PyExc_TypeError, "%.200s%s missing required " - "argument '%s' (pos %d)", - (fname == NULL) ? "function" : fname, - (fname == NULL) ? "" : "()", - kwlist[i], i+1); - return cleanreturn(0, &freelist); - } - } - /* current code reports success when all required args - * fulfilled and no keyword args left, with no further - * validation. XXX Maybe skip this in debug build ? - */ - if (!nkwargs && !skip) { - return cleanreturn(1, &freelist); - } - } - - /* We are into optional args, skip through to any remaining - * keyword args */ - msg = skipitem(&format, p_va, flags); - if (msg) { - PyErr_Format(PyExc_SystemError, "%s: '%s'", msg, - format); - return cleanreturn(0, &freelist); - } - } - - if (skip) { - PyErr_Format(PyExc_TypeError, - "%.200s%s takes %s %d positional argument%s" - " (%zd given)", - (fname == NULL) ? "function" : fname, - (fname == NULL) ? "" : "()", - (Py_MIN(pos, min) < i) ? "at least" : "exactly", - Py_MIN(pos, min), - Py_MIN(pos, min) == 1 ? "" : "s", - nargs); - return cleanreturn(0, &freelist); - } - - if (!IS_END_OF_FORMAT(*format) && (*format != '|') && (*format != '$')) { - PyErr_Format(PyExc_SystemError, - "more argument specifiers than keyword list entries " - "(remaining format:'%s')", format); - return cleanreturn(0, &freelist); - } - - if (nkwargs > 0) { - PyObject *key; - Py_ssize_t j; - /* make sure there are no arguments given by name and position */ - for (i = pos; i < nargs; i++) { - current_arg = _PyDict_GetItemStringWithError(kwargs, kwlist[i]); - if (current_arg) { - /* arg present in tuple and in dict */ - PyErr_Format(PyExc_TypeError, - "argument for %.200s%s given by name ('%s') " - "and position (%d)", - (fname == NULL) ? "function" : fname, - (fname == NULL) ? "" : "()", - kwlist[i], i+1); - return cleanreturn(0, &freelist); - } - else if (PyErr_Occurred()) { - return cleanreturn(0, &freelist); - } - } - /* make sure there are no extraneous keyword arguments */ - j = 0; - while (PyDict_Next(kwargs, &j, &key, NULL)) { - int match = 0; - if (!PyUnicode_Check(key)) { - PyErr_SetString(PyExc_TypeError, - "keywords must be strings"); - return cleanreturn(0, &freelist); - } - for (i = pos; i < len; i++) { - if (_PyUnicode_EqualToASCIIString(key, kwlist[i])) { - match = 1; - break; - } - } - if (!match) { - PyErr_Format(PyExc_TypeError, - "'%U' is an invalid keyword " - "argument for %.200s%s", - key, - (fname == NULL) ? "this function" : fname, - (fname == NULL) ? "" : "()"); - return cleanreturn(0, &freelist); - } - } - } - - return cleanreturn(1, &freelist); -} - - -/* List of static parsers. */ -static struct _PyArg_Parser *static_arg_parsers = NULL; - -static int -parser_init(struct _PyArg_Parser *parser) -{ - const char * const *keywords; - const char *format, *msg; - int i, len, min, max, nkw; - PyObject *kwtuple; - - assert(parser->keywords != NULL); - if (parser->kwtuple != NULL) { - return 1; - } - - keywords = parser->keywords; - /* scan keywords and count the number of positional-only parameters */ - for (i = 0; keywords[i] && !*keywords[i]; i++) { - } - parser->pos = i; - /* scan keywords and get greatest possible nbr of args */ - for (; keywords[i]; i++) { - if (!*keywords[i]) { - PyErr_SetString(PyExc_SystemError, - "Empty keyword parameter name"); - return 0; - } - } - len = i; - - format = parser->format; - if (format) { - /* grab the function name or custom error msg first (mutually exclusive) */ - parser->fname = strchr(parser->format, ':'); - if (parser->fname) { - parser->fname++; - parser->custom_msg = NULL; - } - else { - parser->custom_msg = strchr(parser->format,';'); - if (parser->custom_msg) - parser->custom_msg++; - } - - min = max = INT_MAX; - for (i = 0; i < len; i++) { - if (*format == '|') { - if (min != INT_MAX) { - PyErr_SetString(PyExc_SystemError, - "Invalid format string (| specified twice)"); - return 0; - } - if (max != INT_MAX) { - PyErr_SetString(PyExc_SystemError, - "Invalid format string ($ before |)"); - return 0; - } - min = i; - format++; - } - if (*format == '$') { - if (max != INT_MAX) { - PyErr_SetString(PyExc_SystemError, - "Invalid format string ($ specified twice)"); - return 0; - } - if (i < parser->pos) { - PyErr_SetString(PyExc_SystemError, - "Empty parameter name after $"); - return 0; - } - max = i; - format++; - } - if (IS_END_OF_FORMAT(*format)) { - PyErr_Format(PyExc_SystemError, - "More keyword list entries (%d) than " - "format specifiers (%d)", len, i); - return 0; - } - - msg = skipitem(&format, NULL, 0); - if (msg) { - PyErr_Format(PyExc_SystemError, "%s: '%s'", msg, - format); - return 0; - } - } - parser->min = Py_MIN(min, len); - parser->max = Py_MIN(max, len); - - if (!IS_END_OF_FORMAT(*format) && (*format != '|') && (*format != '$')) { - PyErr_Format(PyExc_SystemError, - "more argument specifiers than keyword list entries " - "(remaining format:'%s')", format); - return 0; - } - } - - nkw = len - parser->pos; - kwtuple = PyTuple_New(nkw); - if (kwtuple == NULL) { - return 0; - } - keywords = parser->keywords + parser->pos; - for (i = 0; i < nkw; i++) { - PyObject *str = PyUnicode_FromString(keywords[i]); - if (str == NULL) { - Py_DECREF(kwtuple); - return 0; - } - PyUnicode_InternInPlace(&str); - PyTuple_SET_ITEM(kwtuple, i, str); - } - parser->kwtuple = kwtuple; - - assert(parser->next == NULL); - parser->next = static_arg_parsers; - static_arg_parsers = parser; - return 1; -} - -static void -parser_clear(struct _PyArg_Parser *parser) -{ - Py_CLEAR(parser->kwtuple); -} - -static PyObject* -find_keyword(PyObject *kwnames, PyObject *const *kwstack, PyObject *key) -{ - Py_ssize_t i, nkwargs; - - nkwargs = PyTuple_GET_SIZE(kwnames); - for (i = 0; i < nkwargs; i++) { - PyObject *kwname = PyTuple_GET_ITEM(kwnames, i); - - /* kwname == key will normally find a match in since keyword keys - should be interned strings; if not retry below in a new loop. */ - if (kwname == key) { - return kwstack[i]; - } - } - - for (i = 0; i < nkwargs; i++) { - PyObject *kwname = PyTuple_GET_ITEM(kwnames, i); - assert(PyUnicode_Check(kwname)); - if (_PyUnicode_EQ(kwname, key)) { - return kwstack[i]; - } - } - return NULL; -} - -static int -vgetargskeywordsfast_impl(PyObject *const *args, Py_ssize_t nargs, - PyObject *kwargs, PyObject *kwnames, - struct _PyArg_Parser *parser, - va_list *p_va, int flags) -{ - PyObject *kwtuple; - char msgbuf[512]; - int levels[32]; - const char *format; - const char *msg; - PyObject *keyword; - int i, pos, len; - Py_ssize_t nkwargs; - PyObject *current_arg; - freelistentry_t static_entries[STATIC_FREELIST_ENTRIES]; - freelist_t freelist; - PyObject *const *kwstack = NULL; - - freelist.entries = static_entries; - freelist.first_available = 0; - freelist.entries_malloced = 0; - - assert(kwargs == NULL || PyDict_Check(kwargs)); - assert(kwargs == NULL || kwnames == NULL); - assert(p_va != NULL); - - if (parser == NULL) { - PyErr_BadInternalCall(); - return 0; - } - - if (kwnames != NULL && !PyTuple_Check(kwnames)) { - PyErr_BadInternalCall(); - return 0; - } - - if (!parser_init(parser)) { - return 0; - } - - kwtuple = parser->kwtuple; - pos = parser->pos; - len = pos + (int)PyTuple_GET_SIZE(kwtuple); - - if (len > STATIC_FREELIST_ENTRIES) { - freelist.entries = PyMem_NEW(freelistentry_t, len); - if (freelist.entries == NULL) { - PyErr_NoMemory(); - return 0; - } - freelist.entries_malloced = 1; - } - - if (kwargs != NULL) { - nkwargs = PyDict_GET_SIZE(kwargs); - } - else if (kwnames != NULL) { - nkwargs = PyTuple_GET_SIZE(kwnames); - kwstack = args + nargs; - } - else { - nkwargs = 0; - } - if (nargs + nkwargs > len) { - /* Adding "keyword" (when nargs == 0) prevents producing wrong error - messages in some special cases (see bpo-31229). */ - PyErr_Format(PyExc_TypeError, - "%.200s%s takes at most %d %sargument%s (%zd given)", - (parser->fname == NULL) ? "function" : parser->fname, - (parser->fname == NULL) ? "" : "()", - len, - (nargs == 0) ? "keyword " : "", - (len == 1) ? "" : "s", - nargs + nkwargs); - return cleanreturn(0, &freelist); - } - if (parser->max < nargs) { - if (parser->max == 0) { - PyErr_Format(PyExc_TypeError, - "%.200s%s takes no positional arguments", - (parser->fname == NULL) ? "function" : parser->fname, - (parser->fname == NULL) ? "" : "()"); - } - else { - PyErr_Format(PyExc_TypeError, - "%.200s%s takes %s %d positional argument%s (%zd given)", - (parser->fname == NULL) ? "function" : parser->fname, - (parser->fname == NULL) ? "" : "()", - (parser->min < parser->max) ? "at most" : "exactly", - parser->max, - parser->max == 1 ? "" : "s", - nargs); - } - return cleanreturn(0, &freelist); - } - - format = parser->format; - /* convert tuple args and keyword args in same loop, using kwtuple to drive process */ - for (i = 0; i < len; i++) { - if (*format == '|') { - format++; - } - if (*format == '$') { - format++; - } - assert(!IS_END_OF_FORMAT(*format)); - - if (i < nargs) { - current_arg = args[i]; - } - else if (nkwargs && i >= pos) { - keyword = PyTuple_GET_ITEM(kwtuple, i - pos); - if (kwargs != NULL) { - current_arg = PyDict_GetItemWithError(kwargs, keyword); - if (!current_arg && PyErr_Occurred()) { - return cleanreturn(0, &freelist); - } - } - else { - current_arg = find_keyword(kwnames, kwstack, keyword); - } - if (current_arg) { - --nkwargs; - } - } - else { - current_arg = NULL; - } - - if (current_arg) { - msg = convertitem(current_arg, &format, p_va, flags, - levels, msgbuf, sizeof(msgbuf), &freelist); - if (msg) { - seterror(i+1, msg, levels, parser->fname, parser->custom_msg); - return cleanreturn(0, &freelist); - } - continue; - } - - if (i < parser->min) { - /* Less arguments than required */ - if (i < pos) { - Py_ssize_t min = Py_MIN(pos, parser->min); - PyErr_Format(PyExc_TypeError, - "%.200s%s takes %s %d positional argument%s" - " (%zd given)", - (parser->fname == NULL) ? "function" : parser->fname, - (parser->fname == NULL) ? "" : "()", - min < parser->max ? "at least" : "exactly", - min, - min == 1 ? "" : "s", - nargs); - } - else { - keyword = PyTuple_GET_ITEM(kwtuple, i - pos); - PyErr_Format(PyExc_TypeError, "%.200s%s missing required " - "argument '%U' (pos %d)", - (parser->fname == NULL) ? "function" : parser->fname, - (parser->fname == NULL) ? "" : "()", - keyword, i+1); - } - return cleanreturn(0, &freelist); - } - /* current code reports success when all required args - * fulfilled and no keyword args left, with no further - * validation. XXX Maybe skip this in debug build ? - */ - if (!nkwargs) { - return cleanreturn(1, &freelist); - } - - /* We are into optional args, skip through to any remaining - * keyword args */ - msg = skipitem(&format, p_va, flags); - assert(msg == NULL); - } - - assert(IS_END_OF_FORMAT(*format) || (*format == '|') || (*format == '$')); - - if (nkwargs > 0) { - Py_ssize_t j; - /* make sure there are no arguments given by name and position */ - for (i = pos; i < nargs; i++) { - keyword = PyTuple_GET_ITEM(kwtuple, i - pos); - if (kwargs != NULL) { - current_arg = PyDict_GetItemWithError(kwargs, keyword); - if (!current_arg && PyErr_Occurred()) { - return cleanreturn(0, &freelist); - } - } - else { - current_arg = find_keyword(kwnames, kwstack, keyword); - } - if (current_arg) { - /* arg present in tuple and in dict */ - PyErr_Format(PyExc_TypeError, - "argument for %.200s%s given by name ('%U') " - "and position (%d)", - (parser->fname == NULL) ? "function" : parser->fname, - (parser->fname == NULL) ? "" : "()", - keyword, i+1); - return cleanreturn(0, &freelist); - } - } - /* make sure there are no extraneous keyword arguments */ - j = 0; - while (1) { - int match; - if (kwargs != NULL) { - if (!PyDict_Next(kwargs, &j, &keyword, NULL)) - break; - } - else { - if (j >= PyTuple_GET_SIZE(kwnames)) - break; - keyword = PyTuple_GET_ITEM(kwnames, j); - j++; - } - - match = PySequence_Contains(kwtuple, keyword); - if (match <= 0) { - if (!match) { - PyErr_Format(PyExc_TypeError, - "'%S' is an invalid keyword " - "argument for %.200s%s", - keyword, - (parser->fname == NULL) ? "this function" : parser->fname, - (parser->fname == NULL) ? "" : "()"); - } - return cleanreturn(0, &freelist); - } - } - } - - return cleanreturn(1, &freelist); -} - -static int -vgetargskeywordsfast(PyObject *args, PyObject *keywords, - struct _PyArg_Parser *parser, va_list *p_va, int flags) -{ - PyObject **stack; - Py_ssize_t nargs; - - if (args == NULL - || !PyTuple_Check(args) - || (keywords != NULL && !PyDict_Check(keywords))) - { - PyErr_BadInternalCall(); - return 0; - } - - stack = _PyTuple_ITEMS(args); - nargs = PyTuple_GET_SIZE(args); - return vgetargskeywordsfast_impl(stack, nargs, keywords, NULL, - parser, p_va, flags); -} - - -#undef _PyArg_UnpackKeywords - -PyObject * const * -_PyArg_UnpackKeywords(PyObject *const *args, Py_ssize_t nargs, - PyObject *kwargs, PyObject *kwnames, - struct _PyArg_Parser *parser, - int minpos, int maxpos, int minkw, - PyObject **buf) -{ - PyObject *kwtuple; - PyObject *keyword; - int i, posonly, minposonly, maxargs; - int reqlimit = minkw ? maxpos + minkw : minpos; - Py_ssize_t nkwargs; - PyObject *current_arg; - PyObject * const *kwstack = NULL; - - assert(kwargs == NULL || PyDict_Check(kwargs)); - assert(kwargs == NULL || kwnames == NULL); - - if (parser == NULL) { - PyErr_BadInternalCall(); - return NULL; - } - - if (kwnames != NULL && !PyTuple_Check(kwnames)) { - PyErr_BadInternalCall(); - return NULL; - } - - if (args == NULL && nargs == 0) { - args = buf; - } - - if (!parser_init(parser)) { - return NULL; - } - - kwtuple = parser->kwtuple; - posonly = parser->pos; - minposonly = Py_MIN(posonly, minpos); - maxargs = posonly + (int)PyTuple_GET_SIZE(kwtuple); - - if (kwargs != NULL) { - nkwargs = PyDict_GET_SIZE(kwargs); - } - else if (kwnames != NULL) { - nkwargs = PyTuple_GET_SIZE(kwnames); - kwstack = args + nargs; - } - else { - nkwargs = 0; - } - if (nkwargs == 0 && minkw == 0 && minpos <= nargs && nargs <= maxpos) { - /* Fast path. */ - return args; - } - if (nargs + nkwargs > maxargs) { - /* Adding "keyword" (when nargs == 0) prevents producing wrong error - messages in some special cases (see bpo-31229). */ - PyErr_Format(PyExc_TypeError, - "%.200s%s takes at most %d %sargument%s (%zd given)", - (parser->fname == NULL) ? "function" : parser->fname, - (parser->fname == NULL) ? "" : "()", - maxargs, - (nargs == 0) ? "keyword " : "", - (maxargs == 1) ? "" : "s", - nargs + nkwargs); - return NULL; - } - if (nargs > maxpos) { - if (maxpos == 0) { - PyErr_Format(PyExc_TypeError, - "%.200s%s takes no positional arguments", - (parser->fname == NULL) ? "function" : parser->fname, - (parser->fname == NULL) ? "" : "()"); - } - else { - PyErr_Format(PyExc_TypeError, - "%.200s%s takes %s %d positional argument%s (%zd given)", - (parser->fname == NULL) ? "function" : parser->fname, - (parser->fname == NULL) ? "" : "()", - (minpos < maxpos) ? "at most" : "exactly", - maxpos, - (maxpos == 1) ? "" : "s", - nargs); - } - return NULL; - } - if (nargs < minposonly) { - PyErr_Format(PyExc_TypeError, - "%.200s%s takes %s %d positional argument%s" - " (%zd given)", - (parser->fname == NULL) ? "function" : parser->fname, - (parser->fname == NULL) ? "" : "()", - minposonly < maxpos ? "at least" : "exactly", - minposonly, - minposonly == 1 ? "" : "s", - nargs); - return NULL; - } - - /* copy tuple args */ - for (i = 0; i < nargs; i++) { - buf[i] = args[i]; - } - - /* copy keyword args using kwtuple to drive process */ - for (i = Py_MAX((int)nargs, posonly); i < maxargs; i++) { - if (nkwargs) { - keyword = PyTuple_GET_ITEM(kwtuple, i - posonly); - if (kwargs != NULL) { - current_arg = PyDict_GetItemWithError(kwargs, keyword); - if (!current_arg && PyErr_Occurred()) { - return NULL; - } - } - else { - current_arg = find_keyword(kwnames, kwstack, keyword); - } - } - else if (i >= reqlimit) { - break; - } - else { - current_arg = NULL; - } - - buf[i] = current_arg; - - if (current_arg) { - --nkwargs; - } - else if (i < minpos || (maxpos <= i && i < reqlimit)) { - /* Less arguments than required */ - keyword = PyTuple_GET_ITEM(kwtuple, i - posonly); - PyErr_Format(PyExc_TypeError, "%.200s%s missing required " - "argument '%U' (pos %d)", - (parser->fname == NULL) ? "function" : parser->fname, - (parser->fname == NULL) ? "" : "()", - keyword, i+1); - return NULL; - } - } - - if (nkwargs > 0) { - Py_ssize_t j; - /* make sure there are no arguments given by name and position */ - for (i = posonly; i < nargs; i++) { - keyword = PyTuple_GET_ITEM(kwtuple, i - posonly); - if (kwargs != NULL) { - current_arg = PyDict_GetItemWithError(kwargs, keyword); - if (!current_arg && PyErr_Occurred()) { - return NULL; - } - } - else { - current_arg = find_keyword(kwnames, kwstack, keyword); - } - if (current_arg) { - /* arg present in tuple and in dict */ - PyErr_Format(PyExc_TypeError, - "argument for %.200s%s given by name ('%U') " - "and position (%d)", - (parser->fname == NULL) ? "function" : parser->fname, - (parser->fname == NULL) ? "" : "()", - keyword, i+1); - return NULL; - } - } - /* make sure there are no extraneous keyword arguments */ - j = 0; - while (1) { - int match; - if (kwargs != NULL) { - if (!PyDict_Next(kwargs, &j, &keyword, NULL)) - break; - } - else { - if (j >= PyTuple_GET_SIZE(kwnames)) - break; - keyword = PyTuple_GET_ITEM(kwnames, j); - j++; - } - - match = PySequence_Contains(kwtuple, keyword); - if (match <= 0) { - if (!match) { - PyErr_Format(PyExc_TypeError, - "'%S' is an invalid keyword " - "argument for %.200s%s", - keyword, - (parser->fname == NULL) ? "this function" : parser->fname, - (parser->fname == NULL) ? "" : "()"); - } - return NULL; - } - } - } - - return buf; -} - - -static const char * -skipitem(const char **p_format, va_list *p_va, int flags) -{ - const char *format = *p_format; - char c = *format++; - - switch (c) { - - /* - * codes that take a single data pointer as an argument - * (the type of the pointer is irrelevant) - */ - - case 'b': /* byte -- very short int */ - case 'B': /* byte as bitfield */ - case 'h': /* short int */ - case 'H': /* short int as bitfield */ - case 'i': /* int */ - case 'I': /* int sized bitfield */ - case 'l': /* long int */ - case 'k': /* long int sized bitfield */ - case 'L': /* long long */ - case 'K': /* long long sized bitfield */ - case 'n': /* Py_ssize_t */ - case 'f': /* float */ - case 'd': /* double */ - case 'D': /* complex double */ - case 'c': /* char */ - case 'C': /* unicode char */ - case 'p': /* boolean predicate */ - case 'S': /* string object */ - case 'Y': /* string object */ - case 'U': /* unicode string object */ - { - if (p_va != NULL) { - (void) va_arg(*p_va, void *); - } - break; - } - - /* string codes */ - - case 'e': /* string with encoding */ - { - if (p_va != NULL) { - (void) va_arg(*p_va, const char *); - } - if (!(*format == 's' || *format == 't')) - /* after 'e', only 's' and 't' is allowed */ - goto err; - format++; - } - /* fall through */ - - case 's': /* string */ - case 'z': /* string or None */ - case 'y': /* bytes */ - case 'u': /* unicode string */ - case 'Z': /* unicode string or None */ - case 'w': /* buffer, read-write */ - { - if (p_va != NULL) { - (void) va_arg(*p_va, char **); - } - if (*format == '#') { - if (p_va != NULL) { - if (!(flags & FLAG_SIZE_T)) { - PyErr_SetString(PyExc_SystemError, - "PY_SSIZE_T_CLEAN macro must be defined for '#' formats"); - return NULL; - } - (void) va_arg(*p_va, Py_ssize_t *); - } - format++; - } else if ((c == 's' || c == 'z' || c == 'y' || c == 'w') - && *format == '*') - { - format++; - } - break; - } - - case 'O': /* object */ - { - if (*format == '!') { - format++; - if (p_va != NULL) { - (void) va_arg(*p_va, PyTypeObject*); - (void) va_arg(*p_va, PyObject **); - } - } - else if (*format == '&') { - typedef int (*converter)(PyObject *, void *); - if (p_va != NULL) { - (void) va_arg(*p_va, converter); - (void) va_arg(*p_va, void *); - } - format++; - } - else { - if (p_va != NULL) { - (void) va_arg(*p_va, PyObject **); - } - } - break; - } - - case '(': /* bypass tuple, not handled at all previously */ - { - const char *msg; - for (;;) { - if (*format==')') - break; - if (IS_END_OF_FORMAT(*format)) - return "Unmatched left paren in format " - "string"; - msg = skipitem(&format, p_va, flags); - if (msg) - return msg; - } - format++; - break; - } - - case ')': - return "Unmatched right paren in format string"; - - default: -err: - return "impossible<bad format char>"; - - } - - *p_format = format; - return NULL; -} - - -#undef _PyArg_CheckPositional - -int -_PyArg_CheckPositional(const char *name, Py_ssize_t nargs, - Py_ssize_t min, Py_ssize_t max) -{ - assert(min >= 0); - assert(min <= max); - - if (nargs < min) { - if (name != NULL) - PyErr_Format( - PyExc_TypeError, - "%.200s expected %s%zd argument%s, got %zd", - name, (min == max ? "" : "at least "), min, min == 1 ? "" : "s", nargs); - else - PyErr_Format( - PyExc_TypeError, - "unpacked tuple should have %s%zd element%s," - " but has %zd", - (min == max ? "" : "at least "), min, min == 1 ? "" : "s", nargs); - return 0; - } - - if (nargs == 0) { - return 1; - } - - if (nargs > max) { - if (name != NULL) - PyErr_Format( - PyExc_TypeError, - "%.200s expected %s%zd argument%s, got %zd", - name, (min == max ? "" : "at most "), max, max == 1 ? "" : "s", nargs); - else - PyErr_Format( - PyExc_TypeError, - "unpacked tuple should have %s%zd element%s," - " but has %zd", - (min == max ? "" : "at most "), max, max == 1 ? "" : "s", nargs); - return 0; - } - - return 1; -} - -static int -unpack_stack(PyObject *const *args, Py_ssize_t nargs, const char *name, - Py_ssize_t min, Py_ssize_t max, va_list vargs) -{ - Py_ssize_t i; - PyObject **o; - - if (!_PyArg_CheckPositional(name, nargs, min, max)) { - return 0; - } - - for (i = 0; i < nargs; i++) { - o = va_arg(vargs, PyObject **); - *o = args[i]; - } - return 1; -} - -int -PyArg_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t max, ...) -{ - PyObject **stack; - Py_ssize_t nargs; - int retval; - va_list vargs; - - if (!PyTuple_Check(args)) { - PyErr_SetString(PyExc_SystemError, - "PyArg_UnpackTuple() argument list is not a tuple"); - return 0; - } - stack = _PyTuple_ITEMS(args); - nargs = PyTuple_GET_SIZE(args); - -#ifdef HAVE_STDARG_PROTOTYPES - va_start(vargs, max); -#else - va_start(vargs); -#endif - retval = unpack_stack(stack, nargs, name, min, max, vargs); - va_end(vargs); - return retval; -} - -int -_PyArg_UnpackStack(PyObject *const *args, Py_ssize_t nargs, const char *name, - Py_ssize_t min, Py_ssize_t max, ...) -{ - int retval; - va_list vargs; - -#ifdef HAVE_STDARG_PROTOTYPES - va_start(vargs, max); -#else - va_start(vargs); -#endif - retval = unpack_stack(args, nargs, name, min, max, vargs); - va_end(vargs); - return retval; -} - - -#undef _PyArg_NoKeywords -#undef _PyArg_NoKwnames -#undef _PyArg_NoPositional - -/* For type constructors that don't take keyword args - * - * Sets a TypeError and returns 0 if the args/kwargs is - * not empty, returns 1 otherwise - */ -int -_PyArg_NoKeywords(const char *funcname, PyObject *kwargs) -{ - if (kwargs == NULL) { - return 1; - } - if (!PyDict_CheckExact(kwargs)) { - PyErr_BadInternalCall(); - return 0; - } - if (PyDict_GET_SIZE(kwargs) == 0) { - return 1; - } - - PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments", - funcname); - return 0; -} - -int -_PyArg_NoPositional(const char *funcname, PyObject *args) -{ - if (args == NULL) - return 1; - if (!PyTuple_CheckExact(args)) { - PyErr_BadInternalCall(); - return 0; - } - if (PyTuple_GET_SIZE(args) == 0) - return 1; - - PyErr_Format(PyExc_TypeError, "%.200s() takes no positional arguments", - funcname); - return 0; -} - -int -_PyArg_NoKwnames(const char *funcname, PyObject *kwnames) -{ - if (kwnames == NULL) { - return 1; - } - - assert(PyTuple_CheckExact(kwnames)); - - if (PyTuple_GET_SIZE(kwnames) == 0) { - return 1; - } - - PyErr_Format(PyExc_TypeError, "%s() takes no keyword arguments", funcname); - return 0; -} - -void -_PyArg_Fini(void) -{ - struct _PyArg_Parser *tmp, *s = static_arg_parsers; - while (s) { - tmp = s->next; - s->next = NULL; - parser_clear(s); - s = tmp; - } - static_arg_parsers = NULL; -} - -#ifdef __cplusplus -}; -#endif diff --git a/contrib/tools/python3/src/Python/getcompiler.c b/contrib/tools/python3/src/Python/getcompiler.c deleted file mode 100644 index a5d26239e87..00000000000 --- a/contrib/tools/python3/src/Python/getcompiler.c +++ /dev/null @@ -1,27 +0,0 @@ - -/* Return the compiler identification, if possible. */ - -#include "Python.h" - -#ifndef COMPILER - -// Note the __clang__ conditional has to come before the __GNUC__ one because -// clang pretends to be GCC. -#if defined(__clang__) -#define COMPILER "[Clang " __clang_version__ "]" -#elif defined(__GNUC__) -#define COMPILER "[GCC " __VERSION__ "]" -// Generic fallbacks. -#elif defined(__cplusplus) -#define COMPILER "[C++]" -#else -#define COMPILER "[C]" -#endif - -#endif /* !COMPILER */ - -const char * -Py_GetCompiler(void) -{ - return COMPILER; -} diff --git a/contrib/tools/python3/src/Python/getcopyright.c b/contrib/tools/python3/src/Python/getcopyright.c deleted file mode 100644 index 88d1d053625..00000000000 --- a/contrib/tools/python3/src/Python/getcopyright.c +++ /dev/null @@ -1,23 +0,0 @@ -/* Return the copyright string. This is updated manually. */ - -#include "Python.h" - -static const char cprt[] = -"\ -Copyright (c) 2001-2022 Python Software Foundation.\n\ -All Rights Reserved.\n\ -\n\ -Copyright (c) 2000 BeOpen.com.\n\ -All Rights Reserved.\n\ -\n\ -Copyright (c) 1995-2001 Corporation for National Research Initiatives.\n\ -All Rights Reserved.\n\ -\n\ -Copyright (c) 1991-1995 Stichting Mathematisch Centrum, Amsterdam.\n\ -All Rights Reserved."; - -const char * -Py_GetCopyright(void) -{ - return cprt; -} diff --git a/contrib/tools/python3/src/Python/getopt.c b/contrib/tools/python3/src/Python/getopt.c deleted file mode 100644 index 2e3891aae2d..00000000000 --- a/contrib/tools/python3/src/Python/getopt.c +++ /dev/null @@ -1,175 +0,0 @@ -/*---------------------------------------------------------------------------* - * <RCS keywords> - * - * C++ Library - * - * Copyright 1992-1994, David Gottner - * - * All Rights Reserved - * - * Permission to use, copy, modify, and distribute this software and its - * documentation for any purpose and without fee is hereby granted, - * provided that the above copyright notice, this permission notice and - * the following disclaimer notice appear unmodified in all copies. - * - * I DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL I - * BE LIABLE FOR ANY SPECIAL, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY - * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA, OR PROFITS, WHETHER - * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT - * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - *---------------------------------------------------------------------------*/ - -/* Modified to support --help and --version, as well as /? on Windows - * by Georg Brandl. */ - -#include <Python.h> -#include <stdio.h> -#include <string.h> -#include <wchar.h> -#include "pycore_getopt.h" - -#ifdef __cplusplus -extern "C" { -#endif - -int _PyOS_opterr = 1; /* generate error messages */ -Py_ssize_t _PyOS_optind = 1; /* index into argv array */ -const wchar_t *_PyOS_optarg = NULL; /* optional argument */ - -static const wchar_t *opt_ptr = L""; - -/* Python command line short and long options */ - -#define SHORT_OPTS L"bBc:dEhiIJm:OqRsStuvVW:xX:?" - -static const _PyOS_LongOption longopts[] = { - {L"check-hash-based-pycs", 1, 0}, - {NULL, 0, 0}, -}; - - -void _PyOS_ResetGetOpt(void) -{ - _PyOS_opterr = 1; - _PyOS_optind = 1; - _PyOS_optarg = NULL; - opt_ptr = L""; -} - -int _PyOS_GetOpt(Py_ssize_t argc, wchar_t * const *argv, int *longindex) -{ - wchar_t *ptr; - wchar_t option; - - if (*opt_ptr == '\0') { - - if (_PyOS_optind >= argc) - return -1; -#ifdef MS_WINDOWS - else if (wcscmp(argv[_PyOS_optind], L"/?") == 0) { - ++_PyOS_optind; - return 'h'; - } -#endif - - else if (argv[_PyOS_optind][0] != L'-' || - argv[_PyOS_optind][1] == L'\0' /* lone dash */ ) - return -1; - - else if (wcscmp(argv[_PyOS_optind], L"--") == 0) { - ++_PyOS_optind; - return -1; - } - - else if (wcscmp(argv[_PyOS_optind], L"--help") == 0) { - ++_PyOS_optind; - return 'h'; - } - - else if (wcscmp(argv[_PyOS_optind], L"--version") == 0) { - ++_PyOS_optind; - return 'V'; - } - - opt_ptr = &argv[_PyOS_optind++][1]; - } - - if ((option = *opt_ptr++) == L'\0') - return -1; - - if (option == L'-') { - // Parse long option. - if (*opt_ptr == L'\0') { - if (_PyOS_opterr) { - fprintf(stderr, "expected long option\n"); - } - return -1; - } - *longindex = 0; - const _PyOS_LongOption *opt; - for (opt = &longopts[*longindex]; opt->name; opt = &longopts[++(*longindex)]) { - if (!wcscmp(opt->name, opt_ptr)) - break; - } - if (!opt->name) { - if (_PyOS_opterr) { - fprintf(stderr, "unknown option %ls\n", argv[_PyOS_optind - 1]); - } - return '_'; - } - opt_ptr = L""; - if (!opt->has_arg) { - return opt->val; - } - if (_PyOS_optind >= argc) { - if (_PyOS_opterr) { - fprintf(stderr, "Argument expected for the %ls options\n", - argv[_PyOS_optind - 1]); - } - return '_'; - } - _PyOS_optarg = argv[_PyOS_optind++]; - return opt->val; - } - - if (option == 'J') { - if (_PyOS_opterr) { - fprintf(stderr, "-J is reserved for Jython\n"); - } - return '_'; - } - - if ((ptr = wcschr(SHORT_OPTS, option)) == NULL) { - if (_PyOS_opterr) { - fprintf(stderr, "Unknown option: -%c\n", (char)option); - } - return '_'; - } - - if (*(ptr + 1) == L':') { - if (*opt_ptr != L'\0') { - _PyOS_optarg = opt_ptr; - opt_ptr = L""; - } - - else { - if (_PyOS_optind >= argc) { - if (_PyOS_opterr) { - fprintf(stderr, - "Argument expected for the -%c option\n", (char)option); - } - return '_'; - } - - _PyOS_optarg = argv[_PyOS_optind++]; - } - } - - return option; -} - -#ifdef __cplusplus -} -#endif - diff --git a/contrib/tools/python3/src/Python/getplatform.c b/contrib/tools/python3/src/Python/getplatform.c deleted file mode 100644 index 81a0f7ac537..00000000000 --- a/contrib/tools/python3/src/Python/getplatform.c +++ /dev/null @@ -1,12 +0,0 @@ - -#include "Python.h" - -#ifndef PLATFORM -#define PLATFORM "unknown" -#endif - -const char * -Py_GetPlatform(void) -{ - return PLATFORM; -} diff --git a/contrib/tools/python3/src/Python/getversion.c b/contrib/tools/python3/src/Python/getversion.c deleted file mode 100644 index c32b6f9d60d..00000000000 --- a/contrib/tools/python3/src/Python/getversion.c +++ /dev/null @@ -1,15 +0,0 @@ - -/* Return the full version string. */ - -#include "Python.h" - -#include "patchlevel.h" - -const char * -Py_GetVersion(void) -{ - static char version[250]; - PyOS_snprintf(version, sizeof(version), "%.80s (%.80s) %.80s", - PY_VERSION, Py_GetBuildInfo(), Py_GetCompiler()); - return version; -} diff --git a/contrib/tools/python3/src/Python/hamt.c b/contrib/tools/python3/src/Python/hamt.c deleted file mode 100644 index 6572a554311..00000000000 --- a/contrib/tools/python3/src/Python/hamt.c +++ /dev/null @@ -1,2985 +0,0 @@ -#include "Python.h" - -#include "pycore_bitutils.h" // _Py_popcount32 -#include "pycore_hamt.h" -#include "pycore_object.h" // _PyObject_GC_TRACK() -#include <stddef.h> // offsetof() - -/* -This file provides an implementation of an immutable mapping using the -Hash Array Mapped Trie (or HAMT) datastructure. - -This design allows to have: - -1. Efficient copy: immutable mappings can be copied by reference, - making it an O(1) operation. - -2. Efficient mutations: due to structural sharing, only a portion of - the trie needs to be copied when the collection is mutated. The - cost of set/delete operations is O(log N). - -3. Efficient lookups: O(log N). - -(where N is number of key/value items in the immutable mapping.) - - -HAMT -==== - -The core idea of HAMT is that the shape of the trie is encoded into the -hashes of keys. - -Say we want to store a K/V pair in our mapping. First, we calculate the -hash of K, let's say it's 19830128, or in binary: - - 0b1001011101001010101110000 = 19830128 - -Now let's partition this bit representation of the hash into blocks of -5 bits each: - - 0b00_00000_10010_11101_00101_01011_10000 = 19830128 - (6) (5) (4) (3) (2) (1) - -Each block of 5 bits represents a number between 0 and 31. So if we have -a tree that consists of nodes, each of which is an array of 32 pointers, -those 5-bit blocks will encode a position on a single tree level. - -For example, storing the key K with hash 19830128, results in the following -tree structure: - - (array of 32 pointers) - +---+ -- +----+----+----+ -- +----+ - root node | 0 | .. | 15 | 16 | 17 | .. | 31 | 0b10000 = 16 (1) - (level 1) +---+ -- +----+----+----+ -- +----+ - | - +---+ -- +----+----+----+ -- +----+ - a 2nd level node | 0 | .. | 10 | 11 | 12 | .. | 31 | 0b01011 = 11 (2) - +---+ -- +----+----+----+ -- +----+ - | - +---+ -- +----+----+----+ -- +----+ - a 3rd level node | 0 | .. | 04 | 05 | 06 | .. | 31 | 0b00101 = 5 (3) - +---+ -- +----+----+----+ -- +----+ - | - +---+ -- +----+----+----+----+ - a 4th level node | 0 | .. | 04 | 29 | 30 | 31 | 0b11101 = 29 (4) - +---+ -- +----+----+----+----+ - | - +---+ -- +----+----+----+ -- +----+ - a 5th level node | 0 | .. | 17 | 18 | 19 | .. | 31 | 0b10010 = 18 (5) - +---+ -- +----+----+----+ -- +----+ - | - +--------------+ - | - +---+ -- +----+----+----+ -- +----+ - a 6th level node | 0 | .. | 15 | 16 | 17 | .. | 31 | 0b00000 = 0 (6) - +---+ -- +----+----+----+ -- +----+ - | - V -- our value (or collision) - -To rehash: for a K/V pair, the hash of K encodes where in the tree V will -be stored. - -To optimize memory footprint and handle hash collisions, our implementation -uses three different types of nodes: - - * A Bitmap node; - * An Array node; - * A Collision node. - -Because we implement an immutable dictionary, our nodes are also -immutable. Therefore, when we need to modify a node, we copy it, and -do that modification to the copy. - - -Array Nodes ------------ - -These nodes are very simple. Essentially they are arrays of 32 pointers -we used to illustrate the high-level idea in the previous section. - -We use Array nodes only when we need to store more than 16 pointers -in a single node. - -Array nodes do not store key objects or value objects. They are used -only as an indirection level - their pointers point to other nodes in -the tree. - - -Bitmap Node ------------ - -Allocating a new 32-pointers array for every node of our tree would be -very expensive. Unless we store millions of keys, most of tree nodes would -be very sparse. - -When we have less than 16 elements in a node, we don't want to use the -Array node, that would mean that we waste a lot of memory. Instead, -we can use bitmap compression and can have just as many pointers -as we need! - -Bitmap nodes consist of two fields: - -1. An array of pointers. If a Bitmap node holds N elements, the - array will be of N pointers. - -2. A 32bit integer -- a bitmap field. If an N-th bit is set in the - bitmap, it means that the node has an N-th element. - -For example, say we need to store a 3 elements sparse array: - - +---+ -- +---+ -- +----+ -- +----+ - | 0 | .. | 4 | .. | 11 | .. | 17 | - +---+ -- +---+ -- +----+ -- +----+ - | | | - o1 o2 o3 - -We allocate a three-pointer Bitmap node. Its bitmap field will be -then set to: - - 0b_00100_00010_00000_10000 == (1 << 17) | (1 << 11) | (1 << 4) - -To check if our Bitmap node has an I-th element we can do: - - bitmap & (1 << I) - - -And here's a formula to calculate a position in our pointer array -which would correspond to an I-th element: - - popcount(bitmap & ((1 << I) - 1)) - - -Let's break it down: - - * `popcount` is a function that returns a number of bits set to 1; - - * `((1 << I) - 1)` is a mask to filter the bitmask to contain bits - set to the *right* of our bit. - - -So for our 17, 11, and 4 indexes: - - * bitmap & ((1 << 17) - 1) == 0b100000010000 => 2 bits are set => index is 2. - - * bitmap & ((1 << 11) - 1) == 0b10000 => 1 bit is set => index is 1. - - * bitmap & ((1 << 4) - 1) == 0b0 => 0 bits are set => index is 0. - - -To conclude: Bitmap nodes are just like Array nodes -- they can store -a number of pointers, but use bitmap compression to eliminate unused -pointers. - - -Bitmap nodes have two pointers for each item: - - +----+----+----+----+ -- +----+----+ - | k1 | v1 | k2 | v2 | .. | kN | vN | - +----+----+----+----+ -- +----+----+ - -When kI == NULL, vI points to another tree level. - -When kI != NULL, the actual key object is stored in kI, and its -value is stored in vI. - - -Collision Nodes ---------------- - -Collision nodes are simple arrays of pointers -- two pointers per -key/value. When there's a hash collision, say for k1/v1 and k2/v2 -we have `hash(k1)==hash(k2)`. Then our collision node will be: - - +----+----+----+----+ - | k1 | v1 | k2 | v2 | - +----+----+----+----+ - - -Tree Structure --------------- - -All nodes are PyObjects. - -The `PyHamtObject` object has a pointer to the root node (h_root), -and has a length field (h_count). - -High-level functions accept a PyHamtObject object and dispatch to -lower-level functions depending on what kind of node h_root points to. - - -Operations -========== - -There are three fundamental operations on an immutable dictionary: - -1. "o.assoc(k, v)" will return a new immutable dictionary, that will be - a copy of "o", but with the "k/v" item set. - - Functions in this file: - - hamt_node_assoc, hamt_node_bitmap_assoc, - hamt_node_array_assoc, hamt_node_collision_assoc - - `hamt_node_assoc` function accepts a node object, and calls - other functions depending on its actual type. - -2. "o.find(k)" will lookup key "k" in "o". - - Functions: - - hamt_node_find, hamt_node_bitmap_find, - hamt_node_array_find, hamt_node_collision_find - -3. "o.without(k)" will return a new immutable dictionary, that will be - a copy of "o", buth without the "k" key. - - Functions: - - hamt_node_without, hamt_node_bitmap_without, - hamt_node_array_without, hamt_node_collision_without - - -Further Reading -=============== - -1. http://blog.higher-order.net/2009/09/08/understanding-clojures-persistenthashmap-deftwice.html - -2. http://blog.higher-order.net/2010/08/16/assoc-and-clojures-persistenthashmap-part-ii.html - -3. Clojure's PersistentHashMap implementation: - https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/PersistentHashMap.java - - -Debug -===== - -The HAMT datatype is accessible for testing purposes under the -`_testcapi` module: - - >>> from _testcapi import hamt - >>> h = hamt() - >>> h2 = h.set('a', 2) - >>> h3 = h2.set('b', 3) - >>> list(h3) - ['a', 'b'] - -When CPython is built in debug mode, a '__dump__()' method is available -to introspect the tree: - - >>> print(h3.__dump__()) - HAMT(len=2): - BitmapNode(size=4 count=2 bitmap=0b110 id=0x10eb9d9e8): - 'a': 2 - 'b': 3 -*/ - - -#define IS_ARRAY_NODE(node) Py_IS_TYPE(node, &_PyHamt_ArrayNode_Type) -#define IS_BITMAP_NODE(node) Py_IS_TYPE(node, &_PyHamt_BitmapNode_Type) -#define IS_COLLISION_NODE(node) Py_IS_TYPE(node, &_PyHamt_CollisionNode_Type) - - -/* Return type for 'find' (lookup a key) functions. - - * F_ERROR - an error occurred; - * F_NOT_FOUND - the key was not found; - * F_FOUND - the key was found. -*/ -typedef enum {F_ERROR, F_NOT_FOUND, F_FOUND} hamt_find_t; - - -/* Return type for 'without' (delete a key) functions. - - * W_ERROR - an error occurred; - * W_NOT_FOUND - the key was not found: there's nothing to delete; - * W_EMPTY - the key was found: the node/tree would be empty - if the key is deleted; - * W_NEWNODE - the key was found: a new node/tree is returned - without that key. -*/ -typedef enum {W_ERROR, W_NOT_FOUND, W_EMPTY, W_NEWNODE} hamt_without_t; - - -/* Low-level iterator protocol type. - - * I_ITEM - a new item has been yielded; - * I_END - the whole tree was visited (similar to StopIteration). -*/ -typedef enum {I_ITEM, I_END} hamt_iter_t; - - -#define HAMT_ARRAY_NODE_SIZE 32 - - -typedef struct { - PyObject_HEAD - PyHamtNode *a_array[HAMT_ARRAY_NODE_SIZE]; - Py_ssize_t a_count; -} PyHamtNode_Array; - - -typedef struct { - PyObject_VAR_HEAD - uint32_t b_bitmap; - PyObject *b_array[1]; -} PyHamtNode_Bitmap; - - -typedef struct { - PyObject_VAR_HEAD - int32_t c_hash; - PyObject *c_array[1]; -} PyHamtNode_Collision; - - -static PyHamtNode_Bitmap *_empty_bitmap_node; -static PyHamtObject *_empty_hamt; - - -static PyHamtObject * -hamt_alloc(void); - -static PyHamtNode * -hamt_node_assoc(PyHamtNode *node, - uint32_t shift, int32_t hash, - PyObject *key, PyObject *val, int* added_leaf); - -static hamt_without_t -hamt_node_without(PyHamtNode *node, - uint32_t shift, int32_t hash, - PyObject *key, - PyHamtNode **new_node); - -static hamt_find_t -hamt_node_find(PyHamtNode *node, - uint32_t shift, int32_t hash, - PyObject *key, PyObject **val); - -#ifdef Py_DEBUG -static int -hamt_node_dump(PyHamtNode *node, - _PyUnicodeWriter *writer, int level); -#endif - -static PyHamtNode * -hamt_node_array_new(Py_ssize_t); - -static PyHamtNode * -hamt_node_collision_new(int32_t hash, Py_ssize_t size); - -static inline Py_ssize_t -hamt_node_collision_count(PyHamtNode_Collision *node); - - -#ifdef Py_DEBUG -static void -_hamt_node_array_validate(void *obj_raw) -{ - PyObject *obj = _PyObject_CAST(obj_raw); - assert(IS_ARRAY_NODE(obj)); - PyHamtNode_Array *node = (PyHamtNode_Array*)obj; - Py_ssize_t i = 0, count = 0; - for (; i < HAMT_ARRAY_NODE_SIZE; i++) { - if (node->a_array[i] != NULL) { - count++; - } - } - assert(count == node->a_count); -} - -#define VALIDATE_ARRAY_NODE(NODE) \ - do { _hamt_node_array_validate(NODE); } while (0); -#else -#define VALIDATE_ARRAY_NODE(NODE) -#endif - - -/* Returns -1 on error */ -static inline int32_t -hamt_hash(PyObject *o) -{ - Py_hash_t hash = PyObject_Hash(o); - -#if SIZEOF_PY_HASH_T <= 4 - return hash; -#else - if (hash == -1) { - /* exception */ - return -1; - } - - /* While it's somewhat suboptimal to reduce Python's 64 bit hash to - 32 bits via XOR, it seems that the resulting hash function - is good enough (this is also how Long type is hashed in Java.) - Storing 10, 100, 1000 Python strings results in a relatively - shallow and uniform tree structure. - - Also it's worth noting that it would be possible to adapt the tree - structure to 64 bit hashes, but that would increase memory pressure - and provide little to no performance benefits for collections with - fewer than billions of key/value pairs. - - Important: do not change this hash reducing function. There are many - tests that need an exact tree shape to cover all code paths and - we do that by specifying concrete values for test data's `__hash__`. - If this function is changed most of the regression tests would - become useless. - */ - int32_t xored = (int32_t)(hash & 0xffffffffl) ^ (int32_t)(hash >> 32); - return xored == -1 ? -2 : xored; -#endif -} - -static inline uint32_t -hamt_mask(int32_t hash, uint32_t shift) -{ - return (((uint32_t)hash >> shift) & 0x01f); -} - -static inline uint32_t -hamt_bitpos(int32_t hash, uint32_t shift) -{ - return (uint32_t)1 << hamt_mask(hash, shift); -} - -static inline uint32_t -hamt_bitindex(uint32_t bitmap, uint32_t bit) -{ - return (uint32_t)_Py_popcount32(bitmap & (bit - 1)); -} - - -/////////////////////////////////// Dump Helpers -#ifdef Py_DEBUG - -static int -_hamt_dump_ident(_PyUnicodeWriter *writer, int level) -{ - /* Write `' ' * level` to the `writer` */ - PyObject *str = NULL; - PyObject *num = NULL; - PyObject *res = NULL; - int ret = -1; - - str = PyUnicode_FromString(" "); - if (str == NULL) { - goto error; - } - - num = PyLong_FromLong((long)level); - if (num == NULL) { - goto error; - } - - res = PyNumber_Multiply(str, num); - if (res == NULL) { - goto error; - } - - ret = _PyUnicodeWriter_WriteStr(writer, res); - -error: - Py_XDECREF(res); - Py_XDECREF(str); - Py_XDECREF(num); - return ret; -} - -static int -_hamt_dump_format(_PyUnicodeWriter *writer, const char *format, ...) -{ - /* A convenient helper combining _PyUnicodeWriter_WriteStr and - PyUnicode_FromFormatV. - */ - PyObject* msg; - int ret; - - va_list vargs; -#ifdef HAVE_STDARG_PROTOTYPES - va_start(vargs, format); -#else - va_start(vargs); -#endif - msg = PyUnicode_FromFormatV(format, vargs); - va_end(vargs); - - if (msg == NULL) { - return -1; - } - - ret = _PyUnicodeWriter_WriteStr(writer, msg); - Py_DECREF(msg); - return ret; -} - -#endif /* Py_DEBUG */ -/////////////////////////////////// Bitmap Node - - -static PyHamtNode * -hamt_node_bitmap_new(Py_ssize_t size) -{ - /* Create a new bitmap node of size 'size' */ - - PyHamtNode_Bitmap *node; - Py_ssize_t i; - - assert(size >= 0); - assert(size % 2 == 0); - - if (size == 0 && _empty_bitmap_node != NULL) { - Py_INCREF(_empty_bitmap_node); - return (PyHamtNode *)_empty_bitmap_node; - } - - /* No freelist; allocate a new bitmap node */ - node = PyObject_GC_NewVar( - PyHamtNode_Bitmap, &_PyHamt_BitmapNode_Type, size); - if (node == NULL) { - return NULL; - } - - Py_SET_SIZE(node, size); - - for (i = 0; i < size; i++) { - node->b_array[i] = NULL; - } - - node->b_bitmap = 0; - - _PyObject_GC_TRACK(node); - - if (size == 0 && _empty_bitmap_node == NULL) { - /* Since bitmap nodes are immutable, we can cache the instance - for size=0 and reuse it whenever we need an empty bitmap node. - */ - _empty_bitmap_node = node; - Py_INCREF(_empty_bitmap_node); - } - - return (PyHamtNode *)node; -} - -static inline Py_ssize_t -hamt_node_bitmap_count(PyHamtNode_Bitmap *node) -{ - return Py_SIZE(node) / 2; -} - -static PyHamtNode_Bitmap * -hamt_node_bitmap_clone(PyHamtNode_Bitmap *node) -{ - /* Clone a bitmap node; return a new one with the same child notes. */ - - PyHamtNode_Bitmap *clone; - Py_ssize_t i; - - clone = (PyHamtNode_Bitmap *)hamt_node_bitmap_new(Py_SIZE(node)); - if (clone == NULL) { - return NULL; - } - - for (i = 0; i < Py_SIZE(node); i++) { - Py_XINCREF(node->b_array[i]); - clone->b_array[i] = node->b_array[i]; - } - - clone->b_bitmap = node->b_bitmap; - return clone; -} - -static PyHamtNode_Bitmap * -hamt_node_bitmap_clone_without(PyHamtNode_Bitmap *o, uint32_t bit) -{ - assert(bit & o->b_bitmap); - assert(hamt_node_bitmap_count(o) > 1); - - PyHamtNode_Bitmap *new = (PyHamtNode_Bitmap *)hamt_node_bitmap_new( - Py_SIZE(o) - 2); - if (new == NULL) { - return NULL; - } - - uint32_t idx = hamt_bitindex(o->b_bitmap, bit); - uint32_t key_idx = 2 * idx; - uint32_t val_idx = key_idx + 1; - uint32_t i; - - for (i = 0; i < key_idx; i++) { - Py_XINCREF(o->b_array[i]); - new->b_array[i] = o->b_array[i]; - } - - assert(Py_SIZE(o) >= 0 && Py_SIZE(o) <= 32); - for (i = val_idx + 1; i < (uint32_t)Py_SIZE(o); i++) { - Py_XINCREF(o->b_array[i]); - new->b_array[i - 2] = o->b_array[i]; - } - - new->b_bitmap = o->b_bitmap & ~bit; - return new; -} - -static PyHamtNode * -hamt_node_new_bitmap_or_collision(uint32_t shift, - PyObject *key1, PyObject *val1, - int32_t key2_hash, - PyObject *key2, PyObject *val2) -{ - /* Helper method. Creates a new node for key1/val and key2/val2 - pairs. - - If key1 hash is equal to the hash of key2, a Collision node - will be created. If they are not equal, a Bitmap node is - created. - */ - - int32_t key1_hash = hamt_hash(key1); - if (key1_hash == -1) { - return NULL; - } - - if (key1_hash == key2_hash) { - PyHamtNode_Collision *n; - n = (PyHamtNode_Collision *)hamt_node_collision_new(key1_hash, 4); - if (n == NULL) { - return NULL; - } - - Py_INCREF(key1); - n->c_array[0] = key1; - Py_INCREF(val1); - n->c_array[1] = val1; - - Py_INCREF(key2); - n->c_array[2] = key2; - Py_INCREF(val2); - n->c_array[3] = val2; - - return (PyHamtNode *)n; - } - else { - int added_leaf = 0; - PyHamtNode *n = hamt_node_bitmap_new(0); - if (n == NULL) { - return NULL; - } - - PyHamtNode *n2 = hamt_node_assoc( - n, shift, key1_hash, key1, val1, &added_leaf); - Py_DECREF(n); - if (n2 == NULL) { - return NULL; - } - - n = hamt_node_assoc(n2, shift, key2_hash, key2, val2, &added_leaf); - Py_DECREF(n2); - if (n == NULL) { - return NULL; - } - - return n; - } -} - -static PyHamtNode * -hamt_node_bitmap_assoc(PyHamtNode_Bitmap *self, - uint32_t shift, int32_t hash, - PyObject *key, PyObject *val, int* added_leaf) -{ - /* assoc operation for bitmap nodes. - - Return: a new node, or self if key/val already is in the - collection. - - 'added_leaf' is later used in '_PyHamt_Assoc' to determine if - `hamt.set(key, val)` increased the size of the collection. - */ - - uint32_t bit = hamt_bitpos(hash, shift); - uint32_t idx = hamt_bitindex(self->b_bitmap, bit); - - /* Bitmap node layout: - - +------+------+------+------+ --- +------+------+ - | key1 | val1 | key2 | val2 | ... | keyN | valN | - +------+------+------+------+ --- +------+------+ - where `N < Py_SIZE(node)`. - - The `node->b_bitmap` field is a bitmap. For a given - `(shift, hash)` pair we can determine: - - - If this node has the corresponding key/val slots. - - The index of key/val slots. - */ - - if (self->b_bitmap & bit) { - /* The key is set in this node */ - - uint32_t key_idx = 2 * idx; - uint32_t val_idx = key_idx + 1; - - assert(val_idx < (size_t)Py_SIZE(self)); - - PyObject *key_or_null = self->b_array[key_idx]; - PyObject *val_or_node = self->b_array[val_idx]; - - if (key_or_null == NULL) { - /* key is NULL. This means that we have a few keys - that have the same (hash, shift) pair. */ - - assert(val_or_node != NULL); - - PyHamtNode *sub_node = hamt_node_assoc( - (PyHamtNode *)val_or_node, - shift + 5, hash, key, val, added_leaf); - if (sub_node == NULL) { - return NULL; - } - - if (val_or_node == (PyObject *)sub_node) { - Py_DECREF(sub_node); - Py_INCREF(self); - return (PyHamtNode *)self; - } - - PyHamtNode_Bitmap *ret = hamt_node_bitmap_clone(self); - if (ret == NULL) { - return NULL; - } - Py_SETREF(ret->b_array[val_idx], (PyObject*)sub_node); - return (PyHamtNode *)ret; - } - - assert(key != NULL); - /* key is not NULL. This means that we have only one other - key in this collection that matches our hash for this shift. */ - - int comp_err = PyObject_RichCompareBool(key, key_or_null, Py_EQ); - if (comp_err < 0) { /* exception in __eq__ */ - return NULL; - } - if (comp_err == 1) { /* key == key_or_null */ - if (val == val_or_node) { - /* we already have the same key/val pair; return self. */ - Py_INCREF(self); - return (PyHamtNode *)self; - } - - /* We're setting a new value for the key we had before. - Make a new bitmap node with a replaced value, and return it. */ - PyHamtNode_Bitmap *ret = hamt_node_bitmap_clone(self); - if (ret == NULL) { - return NULL; - } - Py_INCREF(val); - Py_SETREF(ret->b_array[val_idx], val); - return (PyHamtNode *)ret; - } - - /* It's a new key, and it has the same index as *one* another key. - We have a collision. We need to create a new node which will - combine the existing key and the key we're adding. - - `hamt_node_new_bitmap_or_collision` will either create a new - Collision node if the keys have identical hashes, or - a new Bitmap node. - */ - PyHamtNode *sub_node = hamt_node_new_bitmap_or_collision( - shift + 5, - key_or_null, val_or_node, /* existing key/val */ - hash, - key, val /* new key/val */ - ); - if (sub_node == NULL) { - return NULL; - } - - PyHamtNode_Bitmap *ret = hamt_node_bitmap_clone(self); - if (ret == NULL) { - Py_DECREF(sub_node); - return NULL; - } - Py_SETREF(ret->b_array[key_idx], NULL); - Py_SETREF(ret->b_array[val_idx], (PyObject *)sub_node); - - *added_leaf = 1; - return (PyHamtNode *)ret; - } - else { - /* There was no key before with the same (shift,hash). */ - - uint32_t n = (uint32_t)_Py_popcount32(self->b_bitmap); - - if (n >= 16) { - /* When we have a situation where we want to store more - than 16 nodes at one level of the tree, we no longer - want to use the Bitmap node with bitmap encoding. - - Instead we start using an Array node, which has - simpler (faster) implementation at the expense of - having preallocated 32 pointers for its keys/values - pairs. - - Small hamt objects (<30 keys) usually don't have any - Array nodes at all. Between ~30 and ~400 keys hamt - objects usually have one Array node, and usually it's - a root node. - */ - - uint32_t jdx = hamt_mask(hash, shift); - /* 'jdx' is the index of where the new key should be added - in the new Array node we're about to create. */ - - PyHamtNode *empty = NULL; - PyHamtNode_Array *new_node = NULL; - PyHamtNode *res = NULL; - - /* Create a new Array node. */ - new_node = (PyHamtNode_Array *)hamt_node_array_new(n + 1); - if (new_node == NULL) { - goto fin; - } - - /* Create an empty bitmap node for the next - hamt_node_assoc call. */ - empty = hamt_node_bitmap_new(0); - if (empty == NULL) { - goto fin; - } - - /* Make a new bitmap node for the key/val we're adding. - Set that bitmap node to new-array-node[jdx]. */ - new_node->a_array[jdx] = hamt_node_assoc( - empty, shift + 5, hash, key, val, added_leaf); - if (new_node->a_array[jdx] == NULL) { - goto fin; - } - - /* Copy existing key/value pairs from the current Bitmap - node to the new Array node we've just created. */ - Py_ssize_t i, j; - for (i = 0, j = 0; i < HAMT_ARRAY_NODE_SIZE; i++) { - if (((self->b_bitmap >> i) & 1) != 0) { - /* Ensure we don't accidentally override `jdx` element - we set few lines above. - */ - assert(new_node->a_array[i] == NULL); - - if (self->b_array[j] == NULL) { - new_node->a_array[i] = - (PyHamtNode *)self->b_array[j + 1]; - Py_INCREF(new_node->a_array[i]); - } - else { - int32_t rehash = hamt_hash(self->b_array[j]); - if (rehash == -1) { - goto fin; - } - - new_node->a_array[i] = hamt_node_assoc( - empty, shift + 5, - rehash, - self->b_array[j], - self->b_array[j + 1], - added_leaf); - - if (new_node->a_array[i] == NULL) { - goto fin; - } - } - j += 2; - } - } - - VALIDATE_ARRAY_NODE(new_node) - - /* That's it! */ - res = (PyHamtNode *)new_node; - - fin: - Py_XDECREF(empty); - if (res == NULL) { - Py_XDECREF(new_node); - } - return res; - } - else { - /* We have less than 16 keys at this level; let's just - create a new bitmap node out of this node with the - new key/val pair added. */ - - uint32_t key_idx = 2 * idx; - uint32_t val_idx = key_idx + 1; - uint32_t i; - - *added_leaf = 1; - - /* Allocate new Bitmap node which can have one more key/val - pair in addition to what we have already. */ - PyHamtNode_Bitmap *new_node = - (PyHamtNode_Bitmap *)hamt_node_bitmap_new(2 * (n + 1)); - if (new_node == NULL) { - return NULL; - } - - /* Copy all keys/values that will be before the new key/value - we are adding. */ - for (i = 0; i < key_idx; i++) { - Py_XINCREF(self->b_array[i]); - new_node->b_array[i] = self->b_array[i]; - } - - /* Set the new key/value to the new Bitmap node. */ - Py_INCREF(key); - new_node->b_array[key_idx] = key; - Py_INCREF(val); - new_node->b_array[val_idx] = val; - - /* Copy all keys/values that will be after the new key/value - we are adding. */ - assert(Py_SIZE(self) >= 0 && Py_SIZE(self) <= 32); - for (i = key_idx; i < (uint32_t)Py_SIZE(self); i++) { - Py_XINCREF(self->b_array[i]); - new_node->b_array[i + 2] = self->b_array[i]; - } - - new_node->b_bitmap = self->b_bitmap | bit; - return (PyHamtNode *)new_node; - } - } -} - -static hamt_without_t -hamt_node_bitmap_without(PyHamtNode_Bitmap *self, - uint32_t shift, int32_t hash, - PyObject *key, - PyHamtNode **new_node) -{ - uint32_t bit = hamt_bitpos(hash, shift); - if ((self->b_bitmap & bit) == 0) { - return W_NOT_FOUND; - } - - uint32_t idx = hamt_bitindex(self->b_bitmap, bit); - - uint32_t key_idx = 2 * idx; - uint32_t val_idx = key_idx + 1; - - PyObject *key_or_null = self->b_array[key_idx]; - PyObject *val_or_node = self->b_array[val_idx]; - - if (key_or_null == NULL) { - /* key == NULL means that 'value' is another tree node. */ - - PyHamtNode *sub_node = NULL; - - hamt_without_t res = hamt_node_without( - (PyHamtNode *)val_or_node, - shift + 5, hash, key, &sub_node); - - switch (res) { - case W_EMPTY: - /* It's impossible for us to receive a W_EMPTY here: - - - Array nodes are converted to Bitmap nodes when - we delete 16th item from them; - - - Collision nodes are converted to Bitmap when - there is one item in them; - - - Bitmap node's without() inlines single-item - sub-nodes. - - So in no situation we can have a single-item - Bitmap child of another Bitmap node. - */ - Py_UNREACHABLE(); - - case W_NEWNODE: { - assert(sub_node != NULL); - - if (IS_BITMAP_NODE(sub_node)) { - PyHamtNode_Bitmap *sub_tree = (PyHamtNode_Bitmap *)sub_node; - if (hamt_node_bitmap_count(sub_tree) == 1 && - sub_tree->b_array[0] != NULL) - { - /* A bitmap node with one key/value pair. Just - merge it into this node. - - Note that we don't inline Bitmap nodes that - have a NULL key -- those nodes point to another - tree level, and we cannot simply move tree levels - up or down. - */ - - PyHamtNode_Bitmap *clone = hamt_node_bitmap_clone(self); - if (clone == NULL) { - Py_DECREF(sub_node); - return W_ERROR; - } - - PyObject *key = sub_tree->b_array[0]; - PyObject *val = sub_tree->b_array[1]; - - Py_INCREF(key); - Py_XSETREF(clone->b_array[key_idx], key); - Py_INCREF(val); - Py_SETREF(clone->b_array[val_idx], val); - - Py_DECREF(sub_tree); - - *new_node = (PyHamtNode *)clone; - return W_NEWNODE; - } - } - -#ifdef Py_DEBUG - /* Ensure that Collision.without implementation - converts to Bitmap nodes itself. - */ - if (IS_COLLISION_NODE(sub_node)) { - assert(hamt_node_collision_count( - (PyHamtNode_Collision*)sub_node) > 1); - } -#endif - - PyHamtNode_Bitmap *clone = hamt_node_bitmap_clone(self); - if (clone == NULL) { - return W_ERROR; - } - - Py_SETREF(clone->b_array[val_idx], - (PyObject *)sub_node); /* borrow */ - - *new_node = (PyHamtNode *)clone; - return W_NEWNODE; - } - - case W_ERROR: - case W_NOT_FOUND: - assert(sub_node == NULL); - return res; - - default: - Py_UNREACHABLE(); - } - } - else { - /* We have a regular key/value pair */ - - int cmp = PyObject_RichCompareBool(key_or_null, key, Py_EQ); - if (cmp < 0) { - return W_ERROR; - } - if (cmp == 0) { - return W_NOT_FOUND; - } - - if (hamt_node_bitmap_count(self) == 1) { - return W_EMPTY; - } - - *new_node = (PyHamtNode *) - hamt_node_bitmap_clone_without(self, bit); - if (*new_node == NULL) { - return W_ERROR; - } - - return W_NEWNODE; - } -} - -static hamt_find_t -hamt_node_bitmap_find(PyHamtNode_Bitmap *self, - uint32_t shift, int32_t hash, - PyObject *key, PyObject **val) -{ - /* Lookup a key in a Bitmap node. */ - - uint32_t bit = hamt_bitpos(hash, shift); - uint32_t idx; - uint32_t key_idx; - uint32_t val_idx; - PyObject *key_or_null; - PyObject *val_or_node; - int comp_err; - - if ((self->b_bitmap & bit) == 0) { - return F_NOT_FOUND; - } - - idx = hamt_bitindex(self->b_bitmap, bit); - key_idx = idx * 2; - val_idx = key_idx + 1; - - assert(val_idx < (size_t)Py_SIZE(self)); - - key_or_null = self->b_array[key_idx]; - val_or_node = self->b_array[val_idx]; - - if (key_or_null == NULL) { - /* There are a few keys that have the same hash at the current shift - that match our key. Dispatch the lookup further down the tree. */ - assert(val_or_node != NULL); - return hamt_node_find((PyHamtNode *)val_or_node, - shift + 5, hash, key, val); - } - - /* We have only one key -- a potential match. Let's compare if the - key we are looking at is equal to the key we are looking for. */ - assert(key != NULL); - comp_err = PyObject_RichCompareBool(key, key_or_null, Py_EQ); - if (comp_err < 0) { /* exception in __eq__ */ - return F_ERROR; - } - if (comp_err == 1) { /* key == key_or_null */ - *val = val_or_node; - return F_FOUND; - } - - return F_NOT_FOUND; -} - -static int -hamt_node_bitmap_traverse(PyHamtNode_Bitmap *self, visitproc visit, void *arg) -{ - /* Bitmap's tp_traverse */ - - Py_ssize_t i; - - for (i = Py_SIZE(self); --i >= 0; ) { - Py_VISIT(self->b_array[i]); - } - - return 0; -} - -static void -hamt_node_bitmap_dealloc(PyHamtNode_Bitmap *self) -{ - /* Bitmap's tp_dealloc */ - - Py_ssize_t len = Py_SIZE(self); - Py_ssize_t i; - - PyObject_GC_UnTrack(self); - Py_TRASHCAN_BEGIN(self, hamt_node_bitmap_dealloc) - - if (len > 0) { - i = len; - while (--i >= 0) { - Py_XDECREF(self->b_array[i]); - } - } - - Py_TYPE(self)->tp_free((PyObject *)self); - Py_TRASHCAN_END -} - -#ifdef Py_DEBUG -static int -hamt_node_bitmap_dump(PyHamtNode_Bitmap *node, - _PyUnicodeWriter *writer, int level) -{ - /* Debug build: __dump__() method implementation for Bitmap nodes. */ - - Py_ssize_t i; - PyObject *tmp1; - PyObject *tmp2; - - if (_hamt_dump_ident(writer, level + 1)) { - goto error; - } - - if (_hamt_dump_format(writer, "BitmapNode(size=%zd count=%zd ", - Py_SIZE(node), Py_SIZE(node) / 2)) - { - goto error; - } - - tmp1 = PyLong_FromUnsignedLong(node->b_bitmap); - if (tmp1 == NULL) { - goto error; - } - tmp2 = _PyLong_Format(tmp1, 2); - Py_DECREF(tmp1); - if (tmp2 == NULL) { - goto error; - } - if (_hamt_dump_format(writer, "bitmap=%S id=%p):\n", tmp2, node)) { - Py_DECREF(tmp2); - goto error; - } - Py_DECREF(tmp2); - - for (i = 0; i < Py_SIZE(node); i += 2) { - PyObject *key_or_null = node->b_array[i]; - PyObject *val_or_node = node->b_array[i + 1]; - - if (_hamt_dump_ident(writer, level + 2)) { - goto error; - } - - if (key_or_null == NULL) { - if (_hamt_dump_format(writer, "NULL:\n")) { - goto error; - } - - if (hamt_node_dump((PyHamtNode *)val_or_node, - writer, level + 2)) - { - goto error; - } - } - else { - if (_hamt_dump_format(writer, "%R: %R", key_or_null, - val_or_node)) - { - goto error; - } - } - - if (_hamt_dump_format(writer, "\n")) { - goto error; - } - } - - return 0; -error: - return -1; -} -#endif /* Py_DEBUG */ - - -/////////////////////////////////// Collision Node - - -static PyHamtNode * -hamt_node_collision_new(int32_t hash, Py_ssize_t size) -{ - /* Create a new Collision node. */ - - PyHamtNode_Collision *node; - Py_ssize_t i; - - assert(size >= 4); - assert(size % 2 == 0); - - node = PyObject_GC_NewVar( - PyHamtNode_Collision, &_PyHamt_CollisionNode_Type, size); - if (node == NULL) { - return NULL; - } - - for (i = 0; i < size; i++) { - node->c_array[i] = NULL; - } - - Py_SET_SIZE(node, size); - node->c_hash = hash; - - _PyObject_GC_TRACK(node); - - return (PyHamtNode *)node; -} - -static hamt_find_t -hamt_node_collision_find_index(PyHamtNode_Collision *self, PyObject *key, - Py_ssize_t *idx) -{ - /* Lookup `key` in the Collision node `self`. Set the index of the - found key to 'idx'. */ - - Py_ssize_t i; - PyObject *el; - - for (i = 0; i < Py_SIZE(self); i += 2) { - el = self->c_array[i]; - - assert(el != NULL); - int cmp = PyObject_RichCompareBool(key, el, Py_EQ); - if (cmp < 0) { - return F_ERROR; - } - if (cmp == 1) { - *idx = i; - return F_FOUND; - } - } - - return F_NOT_FOUND; -} - -static PyHamtNode * -hamt_node_collision_assoc(PyHamtNode_Collision *self, - uint32_t shift, int32_t hash, - PyObject *key, PyObject *val, int* added_leaf) -{ - /* Set a new key to this level (currently a Collision node) - of the tree. */ - - if (hash == self->c_hash) { - /* The hash of the 'key' we are adding matches the hash of - other keys in this Collision node. */ - - Py_ssize_t key_idx = -1; - hamt_find_t found; - PyHamtNode_Collision *new_node; - Py_ssize_t i; - - /* Let's try to lookup the new 'key', maybe we already have it. */ - found = hamt_node_collision_find_index(self, key, &key_idx); - switch (found) { - case F_ERROR: - /* Exception. */ - return NULL; - - case F_NOT_FOUND: - /* This is a totally new key. Clone the current node, - add a new key/value to the cloned node. */ - - new_node = (PyHamtNode_Collision *)hamt_node_collision_new( - self->c_hash, Py_SIZE(self) + 2); - if (new_node == NULL) { - return NULL; - } - - for (i = 0; i < Py_SIZE(self); i++) { - Py_INCREF(self->c_array[i]); - new_node->c_array[i] = self->c_array[i]; - } - - Py_INCREF(key); - new_node->c_array[i] = key; - Py_INCREF(val); - new_node->c_array[i + 1] = val; - - *added_leaf = 1; - return (PyHamtNode *)new_node; - - case F_FOUND: - /* There's a key which is equal to the key we are adding. */ - - assert(key_idx >= 0); - assert(key_idx < Py_SIZE(self)); - Py_ssize_t val_idx = key_idx + 1; - - if (self->c_array[val_idx] == val) { - /* We're setting a key/value pair that's already set. */ - Py_INCREF(self); - return (PyHamtNode *)self; - } - - /* We need to replace old value for the key - with a new value. Create a new Collision node.*/ - new_node = (PyHamtNode_Collision *)hamt_node_collision_new( - self->c_hash, Py_SIZE(self)); - if (new_node == NULL) { - return NULL; - } - - /* Copy all elements of the old node to the new one. */ - for (i = 0; i < Py_SIZE(self); i++) { - Py_INCREF(self->c_array[i]); - new_node->c_array[i] = self->c_array[i]; - } - - /* Replace the old value with the new value for the our key. */ - Py_DECREF(new_node->c_array[val_idx]); - Py_INCREF(val); - new_node->c_array[val_idx] = val; - - return (PyHamtNode *)new_node; - - default: - Py_UNREACHABLE(); - } - } - else { - /* The hash of the new key is different from the hash that - all keys of this Collision node have. - - Create a Bitmap node inplace with two children: - key/value pair that we're adding, and the Collision node - we're replacing on this tree level. - */ - - PyHamtNode_Bitmap *new_node; - PyHamtNode *assoc_res; - - new_node = (PyHamtNode_Bitmap *)hamt_node_bitmap_new(2); - if (new_node == NULL) { - return NULL; - } - new_node->b_bitmap = hamt_bitpos(self->c_hash, shift); - Py_INCREF(self); - new_node->b_array[1] = (PyObject*) self; - - assoc_res = hamt_node_bitmap_assoc( - new_node, shift, hash, key, val, added_leaf); - Py_DECREF(new_node); - return assoc_res; - } -} - -static inline Py_ssize_t -hamt_node_collision_count(PyHamtNode_Collision *node) -{ - return Py_SIZE(node) / 2; -} - -static hamt_without_t -hamt_node_collision_without(PyHamtNode_Collision *self, - uint32_t shift, int32_t hash, - PyObject *key, - PyHamtNode **new_node) -{ - if (hash != self->c_hash) { - return W_NOT_FOUND; - } - - Py_ssize_t key_idx = -1; - hamt_find_t found = hamt_node_collision_find_index(self, key, &key_idx); - - switch (found) { - case F_ERROR: - return W_ERROR; - - case F_NOT_FOUND: - return W_NOT_FOUND; - - case F_FOUND: - assert(key_idx >= 0); - assert(key_idx < Py_SIZE(self)); - - Py_ssize_t new_count = hamt_node_collision_count(self) - 1; - - if (new_count == 0) { - /* The node has only one key/value pair and it's for the - key we're trying to delete. So a new node will be empty - after the removal. - */ - return W_EMPTY; - } - - if (new_count == 1) { - /* The node has two keys, and after deletion the - new Collision node would have one. Collision nodes - with one key shouldn't exist, so convert it to a - Bitmap node. - */ - PyHamtNode_Bitmap *node = (PyHamtNode_Bitmap *) - hamt_node_bitmap_new(2); - if (node == NULL) { - return W_ERROR; - } - - if (key_idx == 0) { - Py_INCREF(self->c_array[2]); - node->b_array[0] = self->c_array[2]; - Py_INCREF(self->c_array[3]); - node->b_array[1] = self->c_array[3]; - } - else { - assert(key_idx == 2); - Py_INCREF(self->c_array[0]); - node->b_array[0] = self->c_array[0]; - Py_INCREF(self->c_array[1]); - node->b_array[1] = self->c_array[1]; - } - - node->b_bitmap = hamt_bitpos(hash, shift); - - *new_node = (PyHamtNode *)node; - return W_NEWNODE; - } - - /* Allocate a new Collision node with capacity for one - less key/value pair */ - PyHamtNode_Collision *new = (PyHamtNode_Collision *) - hamt_node_collision_new( - self->c_hash, Py_SIZE(self) - 2); - if (new == NULL) { - return W_ERROR; - } - - /* Copy all other keys from `self` to `new` */ - Py_ssize_t i; - for (i = 0; i < key_idx; i++) { - Py_INCREF(self->c_array[i]); - new->c_array[i] = self->c_array[i]; - } - for (i = key_idx + 2; i < Py_SIZE(self); i++) { - Py_INCREF(self->c_array[i]); - new->c_array[i - 2] = self->c_array[i]; - } - - *new_node = (PyHamtNode*)new; - return W_NEWNODE; - - default: - Py_UNREACHABLE(); - } -} - -static hamt_find_t -hamt_node_collision_find(PyHamtNode_Collision *self, - uint32_t shift, int32_t hash, - PyObject *key, PyObject **val) -{ - /* Lookup `key` in the Collision node `self`. Set the value - for the found key to 'val'. */ - - Py_ssize_t idx = -1; - hamt_find_t res; - - res = hamt_node_collision_find_index(self, key, &idx); - if (res == F_ERROR || res == F_NOT_FOUND) { - return res; - } - - assert(idx >= 0); - assert(idx + 1 < Py_SIZE(self)); - - *val = self->c_array[idx + 1]; - assert(*val != NULL); - - return F_FOUND; -} - - -static int -hamt_node_collision_traverse(PyHamtNode_Collision *self, - visitproc visit, void *arg) -{ - /* Collision's tp_traverse */ - - Py_ssize_t i; - - for (i = Py_SIZE(self); --i >= 0; ) { - Py_VISIT(self->c_array[i]); - } - - return 0; -} - -static void -hamt_node_collision_dealloc(PyHamtNode_Collision *self) -{ - /* Collision's tp_dealloc */ - - Py_ssize_t len = Py_SIZE(self); - - PyObject_GC_UnTrack(self); - Py_TRASHCAN_BEGIN(self, hamt_node_collision_dealloc) - - if (len > 0) { - - while (--len >= 0) { - Py_XDECREF(self->c_array[len]); - } - } - - Py_TYPE(self)->tp_free((PyObject *)self); - Py_TRASHCAN_END -} - -#ifdef Py_DEBUG -static int -hamt_node_collision_dump(PyHamtNode_Collision *node, - _PyUnicodeWriter *writer, int level) -{ - /* Debug build: __dump__() method implementation for Collision nodes. */ - - Py_ssize_t i; - - if (_hamt_dump_ident(writer, level + 1)) { - goto error; - } - - if (_hamt_dump_format(writer, "CollisionNode(size=%zd id=%p):\n", - Py_SIZE(node), node)) - { - goto error; - } - - for (i = 0; i < Py_SIZE(node); i += 2) { - PyObject *key = node->c_array[i]; - PyObject *val = node->c_array[i + 1]; - - if (_hamt_dump_ident(writer, level + 2)) { - goto error; - } - - if (_hamt_dump_format(writer, "%R: %R\n", key, val)) { - goto error; - } - } - - return 0; -error: - return -1; -} -#endif /* Py_DEBUG */ - - -/////////////////////////////////// Array Node - - -static PyHamtNode * -hamt_node_array_new(Py_ssize_t count) -{ - Py_ssize_t i; - - PyHamtNode_Array *node = PyObject_GC_New( - PyHamtNode_Array, &_PyHamt_ArrayNode_Type); - if (node == NULL) { - return NULL; - } - - for (i = 0; i < HAMT_ARRAY_NODE_SIZE; i++) { - node->a_array[i] = NULL; - } - - node->a_count = count; - - _PyObject_GC_TRACK(node); - return (PyHamtNode *)node; -} - -static PyHamtNode_Array * -hamt_node_array_clone(PyHamtNode_Array *node) -{ - PyHamtNode_Array *clone; - Py_ssize_t i; - - VALIDATE_ARRAY_NODE(node) - - /* Create a new Array node. */ - clone = (PyHamtNode_Array *)hamt_node_array_new(node->a_count); - if (clone == NULL) { - return NULL; - } - - /* Copy all elements from the current Array node to the new one. */ - for (i = 0; i < HAMT_ARRAY_NODE_SIZE; i++) { - Py_XINCREF(node->a_array[i]); - clone->a_array[i] = node->a_array[i]; - } - - VALIDATE_ARRAY_NODE(clone) - return clone; -} - -static PyHamtNode * -hamt_node_array_assoc(PyHamtNode_Array *self, - uint32_t shift, int32_t hash, - PyObject *key, PyObject *val, int* added_leaf) -{ - /* Set a new key to this level (currently a Collision node) - of the tree. - - Array nodes don't store values, they can only point to - other nodes. They are simple arrays of 32 BaseNode pointers/ - */ - - uint32_t idx = hamt_mask(hash, shift); - PyHamtNode *node = self->a_array[idx]; - PyHamtNode *child_node; - PyHamtNode_Array *new_node; - Py_ssize_t i; - - if (node == NULL) { - /* There's no child node for the given hash. Create a new - Bitmap node for this key. */ - - PyHamtNode_Bitmap *empty = NULL; - - /* Get an empty Bitmap node to work with. */ - empty = (PyHamtNode_Bitmap *)hamt_node_bitmap_new(0); - if (empty == NULL) { - return NULL; - } - - /* Set key/val to the newly created empty Bitmap, thus - creating a new Bitmap node with our key/value pair. */ - child_node = hamt_node_bitmap_assoc( - empty, - shift + 5, hash, key, val, added_leaf); - Py_DECREF(empty); - if (child_node == NULL) { - return NULL; - } - - /* Create a new Array node. */ - new_node = (PyHamtNode_Array *)hamt_node_array_new(self->a_count + 1); - if (new_node == NULL) { - Py_DECREF(child_node); - return NULL; - } - - /* Copy all elements from the current Array node to the - new one. */ - for (i = 0; i < HAMT_ARRAY_NODE_SIZE; i++) { - Py_XINCREF(self->a_array[i]); - new_node->a_array[i] = self->a_array[i]; - } - - assert(new_node->a_array[idx] == NULL); - new_node->a_array[idx] = child_node; /* borrow */ - VALIDATE_ARRAY_NODE(new_node) - } - else { - /* There's a child node for the given hash. - Set the key to it./ */ - child_node = hamt_node_assoc( - node, shift + 5, hash, key, val, added_leaf); - if (child_node == NULL) { - return NULL; - } - else if (child_node == (PyHamtNode *)self) { - Py_DECREF(child_node); - return (PyHamtNode *)self; - } - - new_node = hamt_node_array_clone(self); - if (new_node == NULL) { - Py_DECREF(child_node); - return NULL; - } - - Py_SETREF(new_node->a_array[idx], child_node); /* borrow */ - VALIDATE_ARRAY_NODE(new_node) - } - - return (PyHamtNode *)new_node; -} - -static hamt_without_t -hamt_node_array_without(PyHamtNode_Array *self, - uint32_t shift, int32_t hash, - PyObject *key, - PyHamtNode **new_node) -{ - uint32_t idx = hamt_mask(hash, shift); - PyHamtNode *node = self->a_array[idx]; - - if (node == NULL) { - return W_NOT_FOUND; - } - - PyHamtNode *sub_node = NULL; - hamt_without_t res = hamt_node_without( - (PyHamtNode *)node, - shift + 5, hash, key, &sub_node); - - switch (res) { - case W_NOT_FOUND: - case W_ERROR: - assert(sub_node == NULL); - return res; - - case W_NEWNODE: { - /* We need to replace a node at the `idx` index. - Clone this node and replace. - */ - assert(sub_node != NULL); - - PyHamtNode_Array *clone = hamt_node_array_clone(self); - if (clone == NULL) { - Py_DECREF(sub_node); - return W_ERROR; - } - - Py_SETREF(clone->a_array[idx], sub_node); /* borrow */ - *new_node = (PyHamtNode*)clone; /* borrow */ - return W_NEWNODE; - } - - case W_EMPTY: { - assert(sub_node == NULL); - /* We need to remove a node at the `idx` index. - Calculate the size of the replacement Array node. - */ - Py_ssize_t new_count = self->a_count - 1; - - if (new_count == 0) { - return W_EMPTY; - } - - if (new_count >= 16) { - /* We convert Bitmap nodes to Array nodes, when a - Bitmap node needs to store more than 15 key/value - pairs. So we will create a new Array node if we - the number of key/values after deletion is still - greater than 15. - */ - - PyHamtNode_Array *new = hamt_node_array_clone(self); - if (new == NULL) { - return W_ERROR; - } - new->a_count = new_count; - Py_CLEAR(new->a_array[idx]); - - *new_node = (PyHamtNode*)new; /* borrow */ - return W_NEWNODE; - } - - /* New Array node would have less than 16 key/value - pairs. We need to create a replacement Bitmap node. */ - - Py_ssize_t bitmap_size = new_count * 2; - uint32_t bitmap = 0; - - PyHamtNode_Bitmap *new = (PyHamtNode_Bitmap *) - hamt_node_bitmap_new(bitmap_size); - if (new == NULL) { - return W_ERROR; - } - - Py_ssize_t new_i = 0; - for (uint32_t i = 0; i < HAMT_ARRAY_NODE_SIZE; i++) { - if (i == idx) { - /* Skip the node we are deleting. */ - continue; - } - - PyHamtNode *node = self->a_array[i]; - if (node == NULL) { - /* Skip any missing nodes. */ - continue; - } - - bitmap |= 1U << i; - - if (IS_BITMAP_NODE(node)) { - PyHamtNode_Bitmap *child = (PyHamtNode_Bitmap *)node; - - if (hamt_node_bitmap_count(child) == 1 && - child->b_array[0] != NULL) - { - /* node is a Bitmap with one key/value pair, just - merge it into the new Bitmap node we're building. - - Note that we don't inline Bitmap nodes that - have a NULL key -- those nodes point to another - tree level, and we cannot simply move tree levels - up or down. - */ - PyObject *key = child->b_array[0]; - PyObject *val = child->b_array[1]; - - Py_INCREF(key); - new->b_array[new_i] = key; - Py_INCREF(val); - new->b_array[new_i + 1] = val; - } - else { - new->b_array[new_i] = NULL; - Py_INCREF(node); - new->b_array[new_i + 1] = (PyObject*)node; - } - } - else { - -#ifdef Py_DEBUG - if (IS_COLLISION_NODE(node)) { - Py_ssize_t child_count = hamt_node_collision_count( - (PyHamtNode_Collision*)node); - assert(child_count > 1); - } - else if (IS_ARRAY_NODE(node)) { - assert(((PyHamtNode_Array*)node)->a_count >= 16); - } -#endif - - /* Just copy the node into our new Bitmap */ - new->b_array[new_i] = NULL; - Py_INCREF(node); - new->b_array[new_i + 1] = (PyObject*)node; - } - - new_i += 2; - } - - new->b_bitmap = bitmap; - *new_node = (PyHamtNode*)new; /* borrow */ - return W_NEWNODE; - } - - default: - Py_UNREACHABLE(); - } -} - -static hamt_find_t -hamt_node_array_find(PyHamtNode_Array *self, - uint32_t shift, int32_t hash, - PyObject *key, PyObject **val) -{ - /* Lookup `key` in the Array node `self`. Set the value - for the found key to 'val'. */ - - uint32_t idx = hamt_mask(hash, shift); - PyHamtNode *node; - - node = self->a_array[idx]; - if (node == NULL) { - return F_NOT_FOUND; - } - - /* Dispatch to the generic hamt_node_find */ - return hamt_node_find(node, shift + 5, hash, key, val); -} - -static int -hamt_node_array_traverse(PyHamtNode_Array *self, - visitproc visit, void *arg) -{ - /* Array's tp_traverse */ - - Py_ssize_t i; - - for (i = 0; i < HAMT_ARRAY_NODE_SIZE; i++) { - Py_VISIT(self->a_array[i]); - } - - return 0; -} - -static void -hamt_node_array_dealloc(PyHamtNode_Array *self) -{ - /* Array's tp_dealloc */ - - Py_ssize_t i; - - PyObject_GC_UnTrack(self); - Py_TRASHCAN_BEGIN(self, hamt_node_array_dealloc) - - for (i = 0; i < HAMT_ARRAY_NODE_SIZE; i++) { - Py_XDECREF(self->a_array[i]); - } - - Py_TYPE(self)->tp_free((PyObject *)self); - Py_TRASHCAN_END -} - -#ifdef Py_DEBUG -static int -hamt_node_array_dump(PyHamtNode_Array *node, - _PyUnicodeWriter *writer, int level) -{ - /* Debug build: __dump__() method implementation for Array nodes. */ - - Py_ssize_t i; - - if (_hamt_dump_ident(writer, level + 1)) { - goto error; - } - - if (_hamt_dump_format(writer, "ArrayNode(id=%p):\n", node)) { - goto error; - } - - for (i = 0; i < HAMT_ARRAY_NODE_SIZE; i++) { - if (node->a_array[i] == NULL) { - continue; - } - - if (_hamt_dump_ident(writer, level + 2)) { - goto error; - } - - if (_hamt_dump_format(writer, "%zd::\n", i)) { - goto error; - } - - if (hamt_node_dump(node->a_array[i], writer, level + 1)) { - goto error; - } - - if (_hamt_dump_format(writer, "\n")) { - goto error; - } - } - - return 0; -error: - return -1; -} -#endif /* Py_DEBUG */ - - -/////////////////////////////////// Node Dispatch - - -static PyHamtNode * -hamt_node_assoc(PyHamtNode *node, - uint32_t shift, int32_t hash, - PyObject *key, PyObject *val, int* added_leaf) -{ - /* Set key/value to the 'node' starting with the given shift/hash. - Return a new node, or the same node if key/value already - set. - - added_leaf will be set to 1 if key/value wasn't in the - tree before. - - This method automatically dispatches to the suitable - hamt_node_{nodetype}_assoc method. - */ - - if (IS_BITMAP_NODE(node)) { - return hamt_node_bitmap_assoc( - (PyHamtNode_Bitmap *)node, - shift, hash, key, val, added_leaf); - } - else if (IS_ARRAY_NODE(node)) { - return hamt_node_array_assoc( - (PyHamtNode_Array *)node, - shift, hash, key, val, added_leaf); - } - else { - assert(IS_COLLISION_NODE(node)); - return hamt_node_collision_assoc( - (PyHamtNode_Collision *)node, - shift, hash, key, val, added_leaf); - } -} - -static hamt_without_t -hamt_node_without(PyHamtNode *node, - uint32_t shift, int32_t hash, - PyObject *key, - PyHamtNode **new_node) -{ - if (IS_BITMAP_NODE(node)) { - return hamt_node_bitmap_without( - (PyHamtNode_Bitmap *)node, - shift, hash, key, - new_node); - } - else if (IS_ARRAY_NODE(node)) { - return hamt_node_array_without( - (PyHamtNode_Array *)node, - shift, hash, key, - new_node); - } - else { - assert(IS_COLLISION_NODE(node)); - return hamt_node_collision_without( - (PyHamtNode_Collision *)node, - shift, hash, key, - new_node); - } -} - -static hamt_find_t -hamt_node_find(PyHamtNode *node, - uint32_t shift, int32_t hash, - PyObject *key, PyObject **val) -{ - /* Find the key in the node starting with the given shift/hash. - - If a value is found, the result will be set to F_FOUND, and - *val will point to the found value object. - - If a value wasn't found, the result will be set to F_NOT_FOUND. - - If an exception occurs during the call, the result will be F_ERROR. - - This method automatically dispatches to the suitable - hamt_node_{nodetype}_find method. - */ - - if (IS_BITMAP_NODE(node)) { - return hamt_node_bitmap_find( - (PyHamtNode_Bitmap *)node, - shift, hash, key, val); - - } - else if (IS_ARRAY_NODE(node)) { - return hamt_node_array_find( - (PyHamtNode_Array *)node, - shift, hash, key, val); - } - else { - assert(IS_COLLISION_NODE(node)); - return hamt_node_collision_find( - (PyHamtNode_Collision *)node, - shift, hash, key, val); - } -} - -#ifdef Py_DEBUG -static int -hamt_node_dump(PyHamtNode *node, - _PyUnicodeWriter *writer, int level) -{ - /* Debug build: __dump__() method implementation for a node. - - This method automatically dispatches to the suitable - hamt_node_{nodetype})_dump method. - */ - - if (IS_BITMAP_NODE(node)) { - return hamt_node_bitmap_dump( - (PyHamtNode_Bitmap *)node, writer, level); - } - else if (IS_ARRAY_NODE(node)) { - return hamt_node_array_dump( - (PyHamtNode_Array *)node, writer, level); - } - else { - assert(IS_COLLISION_NODE(node)); - return hamt_node_collision_dump( - (PyHamtNode_Collision *)node, writer, level); - } -} -#endif /* Py_DEBUG */ - - -/////////////////////////////////// Iterators: Machinery - - -static hamt_iter_t -hamt_iterator_next(PyHamtIteratorState *iter, PyObject **key, PyObject **val); - - -static void -hamt_iterator_init(PyHamtIteratorState *iter, PyHamtNode *root) -{ - for (uint32_t i = 0; i < _Py_HAMT_MAX_TREE_DEPTH; i++) { - iter->i_nodes[i] = NULL; - iter->i_pos[i] = 0; - } - - iter->i_level = 0; - - /* Note: we don't incref/decref nodes in i_nodes. */ - iter->i_nodes[0] = root; -} - -static hamt_iter_t -hamt_iterator_bitmap_next(PyHamtIteratorState *iter, - PyObject **key, PyObject **val) -{ - int8_t level = iter->i_level; - - PyHamtNode_Bitmap *node = (PyHamtNode_Bitmap *)(iter->i_nodes[level]); - Py_ssize_t pos = iter->i_pos[level]; - - if (pos + 1 >= Py_SIZE(node)) { -#ifdef Py_DEBUG - assert(iter->i_level >= 0); - iter->i_nodes[iter->i_level] = NULL; -#endif - iter->i_level--; - return hamt_iterator_next(iter, key, val); - } - - if (node->b_array[pos] == NULL) { - iter->i_pos[level] = pos + 2; - - int8_t next_level = level + 1; - assert(next_level < _Py_HAMT_MAX_TREE_DEPTH); - iter->i_level = next_level; - iter->i_pos[next_level] = 0; - iter->i_nodes[next_level] = (PyHamtNode *) - node->b_array[pos + 1]; - - return hamt_iterator_next(iter, key, val); - } - - *key = node->b_array[pos]; - *val = node->b_array[pos + 1]; - iter->i_pos[level] = pos + 2; - return I_ITEM; -} - -static hamt_iter_t -hamt_iterator_collision_next(PyHamtIteratorState *iter, - PyObject **key, PyObject **val) -{ - int8_t level = iter->i_level; - - PyHamtNode_Collision *node = (PyHamtNode_Collision *)(iter->i_nodes[level]); - Py_ssize_t pos = iter->i_pos[level]; - - if (pos + 1 >= Py_SIZE(node)) { -#ifdef Py_DEBUG - assert(iter->i_level >= 0); - iter->i_nodes[iter->i_level] = NULL; -#endif - iter->i_level--; - return hamt_iterator_next(iter, key, val); - } - - *key = node->c_array[pos]; - *val = node->c_array[pos + 1]; - iter->i_pos[level] = pos + 2; - return I_ITEM; -} - -static hamt_iter_t -hamt_iterator_array_next(PyHamtIteratorState *iter, - PyObject **key, PyObject **val) -{ - int8_t level = iter->i_level; - - PyHamtNode_Array *node = (PyHamtNode_Array *)(iter->i_nodes[level]); - Py_ssize_t pos = iter->i_pos[level]; - - if (pos >= HAMT_ARRAY_NODE_SIZE) { -#ifdef Py_DEBUG - assert(iter->i_level >= 0); - iter->i_nodes[iter->i_level] = NULL; -#endif - iter->i_level--; - return hamt_iterator_next(iter, key, val); - } - - for (Py_ssize_t i = pos; i < HAMT_ARRAY_NODE_SIZE; i++) { - if (node->a_array[i] != NULL) { - iter->i_pos[level] = i + 1; - - int8_t next_level = level + 1; - assert(next_level < _Py_HAMT_MAX_TREE_DEPTH); - iter->i_pos[next_level] = 0; - iter->i_nodes[next_level] = node->a_array[i]; - iter->i_level = next_level; - - return hamt_iterator_next(iter, key, val); - } - } - -#ifdef Py_DEBUG - assert(iter->i_level >= 0); - iter->i_nodes[iter->i_level] = NULL; -#endif - - iter->i_level--; - return hamt_iterator_next(iter, key, val); -} - -static hamt_iter_t -hamt_iterator_next(PyHamtIteratorState *iter, PyObject **key, PyObject **val) -{ - if (iter->i_level < 0) { - return I_END; - } - - assert(iter->i_level < _Py_HAMT_MAX_TREE_DEPTH); - - PyHamtNode *current = iter->i_nodes[iter->i_level]; - - if (IS_BITMAP_NODE(current)) { - return hamt_iterator_bitmap_next(iter, key, val); - } - else if (IS_ARRAY_NODE(current)) { - return hamt_iterator_array_next(iter, key, val); - } - else { - assert(IS_COLLISION_NODE(current)); - return hamt_iterator_collision_next(iter, key, val); - } -} - - -/////////////////////////////////// HAMT high-level functions - - -PyHamtObject * -_PyHamt_Assoc(PyHamtObject *o, PyObject *key, PyObject *val) -{ - int32_t key_hash; - int added_leaf = 0; - PyHamtNode *new_root; - PyHamtObject *new_o; - - key_hash = hamt_hash(key); - if (key_hash == -1) { - return NULL; - } - - new_root = hamt_node_assoc( - (PyHamtNode *)(o->h_root), - 0, key_hash, key, val, &added_leaf); - if (new_root == NULL) { - return NULL; - } - - if (new_root == o->h_root) { - Py_DECREF(new_root); - Py_INCREF(o); - return o; - } - - new_o = hamt_alloc(); - if (new_o == NULL) { - Py_DECREF(new_root); - return NULL; - } - - new_o->h_root = new_root; /* borrow */ - new_o->h_count = added_leaf ? o->h_count + 1 : o->h_count; - - return new_o; -} - -PyHamtObject * -_PyHamt_Without(PyHamtObject *o, PyObject *key) -{ - int32_t key_hash = hamt_hash(key); - if (key_hash == -1) { - return NULL; - } - - PyHamtNode *new_root = NULL; - - hamt_without_t res = hamt_node_without( - (PyHamtNode *)(o->h_root), - 0, key_hash, key, - &new_root); - - switch (res) { - case W_ERROR: - return NULL; - case W_EMPTY: - return _PyHamt_New(); - case W_NOT_FOUND: - Py_INCREF(o); - return o; - case W_NEWNODE: { - assert(new_root != NULL); - - PyHamtObject *new_o = hamt_alloc(); - if (new_o == NULL) { - Py_DECREF(new_root); - return NULL; - } - - new_o->h_root = new_root; /* borrow */ - new_o->h_count = o->h_count - 1; - assert(new_o->h_count >= 0); - return new_o; - } - default: - Py_UNREACHABLE(); - } -} - -static hamt_find_t -hamt_find(PyHamtObject *o, PyObject *key, PyObject **val) -{ - if (o->h_count == 0) { - return F_NOT_FOUND; - } - - int32_t key_hash = hamt_hash(key); - if (key_hash == -1) { - return F_ERROR; - } - - return hamt_node_find(o->h_root, 0, key_hash, key, val); -} - - -int -_PyHamt_Find(PyHamtObject *o, PyObject *key, PyObject **val) -{ - hamt_find_t res = hamt_find(o, key, val); - switch (res) { - case F_ERROR: - return -1; - case F_NOT_FOUND: - return 0; - case F_FOUND: - return 1; - default: - Py_UNREACHABLE(); - } -} - - -int -_PyHamt_Eq(PyHamtObject *v, PyHamtObject *w) -{ - if (v == w) { - return 1; - } - - if (v->h_count != w->h_count) { - return 0; - } - - PyHamtIteratorState iter; - hamt_iter_t iter_res; - hamt_find_t find_res; - PyObject *v_key; - PyObject *v_val; - PyObject *w_val; - - hamt_iterator_init(&iter, v->h_root); - - do { - iter_res = hamt_iterator_next(&iter, &v_key, &v_val); - if (iter_res == I_ITEM) { - find_res = hamt_find(w, v_key, &w_val); - switch (find_res) { - case F_ERROR: - return -1; - - case F_NOT_FOUND: - return 0; - - case F_FOUND: { - int cmp = PyObject_RichCompareBool(v_val, w_val, Py_EQ); - if (cmp < 0) { - return -1; - } - if (cmp == 0) { - return 0; - } - } - } - } - } while (iter_res != I_END); - - return 1; -} - -Py_ssize_t -_PyHamt_Len(PyHamtObject *o) -{ - return o->h_count; -} - -static PyHamtObject * -hamt_alloc(void) -{ - PyHamtObject *o; - o = PyObject_GC_New(PyHamtObject, &_PyHamt_Type); - if (o == NULL) { - return NULL; - } - o->h_count = 0; - o->h_root = NULL; - o->h_weakreflist = NULL; - PyObject_GC_Track(o); - return o; -} - -PyHamtObject * -_PyHamt_New(void) -{ - if (_empty_hamt != NULL) { - /* HAMT is an immutable object so we can easily cache an - empty instance. */ - Py_INCREF(_empty_hamt); - return _empty_hamt; - } - - PyHamtObject *o = hamt_alloc(); - if (o == NULL) { - return NULL; - } - - o->h_root = hamt_node_bitmap_new(0); - if (o->h_root == NULL) { - Py_DECREF(o); - return NULL; - } - - o->h_count = 0; - - if (_empty_hamt == NULL) { - Py_INCREF(o); - _empty_hamt = o; - } - - return o; -} - -#ifdef Py_DEBUG -static PyObject * -hamt_dump(PyHamtObject *self) -{ - _PyUnicodeWriter writer; - - _PyUnicodeWriter_Init(&writer); - - if (_hamt_dump_format(&writer, "HAMT(len=%zd):\n", self->h_count)) { - goto error; - } - - if (hamt_node_dump(self->h_root, &writer, 0)) { - goto error; - } - - return _PyUnicodeWriter_Finish(&writer); - -error: - _PyUnicodeWriter_Dealloc(&writer); - return NULL; -} -#endif /* Py_DEBUG */ - - -/////////////////////////////////// Iterators: Shared Iterator Implementation - - -static int -hamt_baseiter_tp_clear(PyHamtIterator *it) -{ - Py_CLEAR(it->hi_obj); - return 0; -} - -static void -hamt_baseiter_tp_dealloc(PyHamtIterator *it) -{ - PyObject_GC_UnTrack(it); - (void)hamt_baseiter_tp_clear(it); - PyObject_GC_Del(it); -} - -static int -hamt_baseiter_tp_traverse(PyHamtIterator *it, visitproc visit, void *arg) -{ - Py_VISIT(it->hi_obj); - return 0; -} - -static PyObject * -hamt_baseiter_tp_iternext(PyHamtIterator *it) -{ - PyObject *key; - PyObject *val; - hamt_iter_t res = hamt_iterator_next(&it->hi_iter, &key, &val); - - switch (res) { - case I_END: - PyErr_SetNone(PyExc_StopIteration); - return NULL; - - case I_ITEM: { - return (*(it->hi_yield))(key, val); - } - - default: { - Py_UNREACHABLE(); - } - } -} - -static Py_ssize_t -hamt_baseiter_tp_len(PyHamtIterator *it) -{ - return it->hi_obj->h_count; -} - -static PyMappingMethods PyHamtIterator_as_mapping = { - (lenfunc)hamt_baseiter_tp_len, -}; - -static PyObject * -hamt_baseiter_new(PyTypeObject *type, binaryfunc yield, PyHamtObject *o) -{ - PyHamtIterator *it = PyObject_GC_New(PyHamtIterator, type); - if (it == NULL) { - return NULL; - } - - Py_INCREF(o); - it->hi_obj = o; - it->hi_yield = yield; - - hamt_iterator_init(&it->hi_iter, o->h_root); - - return (PyObject*)it; -} - -#define ITERATOR_TYPE_SHARED_SLOTS \ - .tp_basicsize = sizeof(PyHamtIterator), \ - .tp_itemsize = 0, \ - .tp_as_mapping = &PyHamtIterator_as_mapping, \ - .tp_dealloc = (destructor)hamt_baseiter_tp_dealloc, \ - .tp_getattro = PyObject_GenericGetAttr, \ - .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, \ - .tp_traverse = (traverseproc)hamt_baseiter_tp_traverse, \ - .tp_clear = (inquiry)hamt_baseiter_tp_clear, \ - .tp_iter = PyObject_SelfIter, \ - .tp_iternext = (iternextfunc)hamt_baseiter_tp_iternext, - - -/////////////////////////////////// _PyHamtItems_Type - - -PyTypeObject _PyHamtItems_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "items", - ITERATOR_TYPE_SHARED_SLOTS -}; - -static PyObject * -hamt_iter_yield_items(PyObject *key, PyObject *val) -{ - return PyTuple_Pack(2, key, val); -} - -PyObject * -_PyHamt_NewIterItems(PyHamtObject *o) -{ - return hamt_baseiter_new( - &_PyHamtItems_Type, hamt_iter_yield_items, o); -} - - -/////////////////////////////////// _PyHamtKeys_Type - - -PyTypeObject _PyHamtKeys_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "keys", - ITERATOR_TYPE_SHARED_SLOTS -}; - -static PyObject * -hamt_iter_yield_keys(PyObject *key, PyObject *val) -{ - Py_INCREF(key); - return key; -} - -PyObject * -_PyHamt_NewIterKeys(PyHamtObject *o) -{ - return hamt_baseiter_new( - &_PyHamtKeys_Type, hamt_iter_yield_keys, o); -} - - -/////////////////////////////////// _PyHamtValues_Type - - -PyTypeObject _PyHamtValues_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "values", - ITERATOR_TYPE_SHARED_SLOTS -}; - -static PyObject * -hamt_iter_yield_values(PyObject *key, PyObject *val) -{ - Py_INCREF(val); - return val; -} - -PyObject * -_PyHamt_NewIterValues(PyHamtObject *o) -{ - return hamt_baseiter_new( - &_PyHamtValues_Type, hamt_iter_yield_values, o); -} - - -/////////////////////////////////// _PyHamt_Type - - -#ifdef Py_DEBUG -static PyObject * -hamt_dump(PyHamtObject *self); -#endif - - -static PyObject * -hamt_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - return (PyObject*)_PyHamt_New(); -} - -static int -hamt_tp_clear(PyHamtObject *self) -{ - Py_CLEAR(self->h_root); - return 0; -} - - -static int -hamt_tp_traverse(PyHamtObject *self, visitproc visit, void *arg) -{ - Py_VISIT(self->h_root); - return 0; -} - -static void -hamt_tp_dealloc(PyHamtObject *self) -{ - PyObject_GC_UnTrack(self); - if (self->h_weakreflist != NULL) { - PyObject_ClearWeakRefs((PyObject*)self); - } - (void)hamt_tp_clear(self); - Py_TYPE(self)->tp_free(self); -} - - -static PyObject * -hamt_tp_richcompare(PyObject *v, PyObject *w, int op) -{ - if (!PyHamt_Check(v) || !PyHamt_Check(w) || (op != Py_EQ && op != Py_NE)) { - Py_RETURN_NOTIMPLEMENTED; - } - - int res = _PyHamt_Eq((PyHamtObject *)v, (PyHamtObject *)w); - if (res < 0) { - return NULL; - } - - if (op == Py_NE) { - res = !res; - } - - if (res) { - Py_RETURN_TRUE; - } - else { - Py_RETURN_FALSE; - } -} - -static int -hamt_tp_contains(PyHamtObject *self, PyObject *key) -{ - PyObject *val; - return _PyHamt_Find(self, key, &val); -} - -static PyObject * -hamt_tp_subscript(PyHamtObject *self, PyObject *key) -{ - PyObject *val; - hamt_find_t res = hamt_find(self, key, &val); - switch (res) { - case F_ERROR: - return NULL; - case F_FOUND: - Py_INCREF(val); - return val; - case F_NOT_FOUND: - PyErr_SetObject(PyExc_KeyError, key); - return NULL; - default: - Py_UNREACHABLE(); - } -} - -static Py_ssize_t -hamt_tp_len(PyHamtObject *self) -{ - return _PyHamt_Len(self); -} - -static PyObject * -hamt_tp_iter(PyHamtObject *self) -{ - return _PyHamt_NewIterKeys(self); -} - -static PyObject * -hamt_py_set(PyHamtObject *self, PyObject *args) -{ - PyObject *key; - PyObject *val; - - if (!PyArg_UnpackTuple(args, "set", 2, 2, &key, &val)) { - return NULL; - } - - return (PyObject *)_PyHamt_Assoc(self, key, val); -} - -static PyObject * -hamt_py_get(PyHamtObject *self, PyObject *args) -{ - PyObject *key; - PyObject *def = NULL; - - if (!PyArg_UnpackTuple(args, "get", 1, 2, &key, &def)) { - return NULL; - } - - PyObject *val = NULL; - hamt_find_t res = hamt_find(self, key, &val); - switch (res) { - case F_ERROR: - return NULL; - case F_FOUND: - Py_INCREF(val); - return val; - case F_NOT_FOUND: - if (def == NULL) { - Py_RETURN_NONE; - } - Py_INCREF(def); - return def; - default: - Py_UNREACHABLE(); - } -} - -static PyObject * -hamt_py_delete(PyHamtObject *self, PyObject *key) -{ - return (PyObject *)_PyHamt_Without(self, key); -} - -static PyObject * -hamt_py_items(PyHamtObject *self, PyObject *args) -{ - return _PyHamt_NewIterItems(self); -} - -static PyObject * -hamt_py_values(PyHamtObject *self, PyObject *args) -{ - return _PyHamt_NewIterValues(self); -} - -static PyObject * -hamt_py_keys(PyHamtObject *self, PyObject *args) -{ - return _PyHamt_NewIterKeys(self); -} - -#ifdef Py_DEBUG -static PyObject * -hamt_py_dump(PyHamtObject *self, PyObject *args) -{ - return hamt_dump(self); -} -#endif - - -static PyMethodDef PyHamt_methods[] = { - {"set", (PyCFunction)hamt_py_set, METH_VARARGS, NULL}, - {"get", (PyCFunction)hamt_py_get, METH_VARARGS, NULL}, - {"delete", (PyCFunction)hamt_py_delete, METH_O, NULL}, - {"items", (PyCFunction)hamt_py_items, METH_NOARGS, NULL}, - {"keys", (PyCFunction)hamt_py_keys, METH_NOARGS, NULL}, - {"values", (PyCFunction)hamt_py_values, METH_NOARGS, NULL}, -#ifdef Py_DEBUG - {"__dump__", (PyCFunction)hamt_py_dump, METH_NOARGS, NULL}, -#endif - {NULL, NULL} -}; - -static PySequenceMethods PyHamt_as_sequence = { - 0, /* sq_length */ - 0, /* sq_concat */ - 0, /* sq_repeat */ - 0, /* sq_item */ - 0, /* sq_slice */ - 0, /* sq_ass_item */ - 0, /* sq_ass_slice */ - (objobjproc)hamt_tp_contains, /* sq_contains */ - 0, /* sq_inplace_concat */ - 0, /* sq_inplace_repeat */ -}; - -static PyMappingMethods PyHamt_as_mapping = { - (lenfunc)hamt_tp_len, /* mp_length */ - (binaryfunc)hamt_tp_subscript, /* mp_subscript */ -}; - -PyTypeObject _PyHamt_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "hamt", - sizeof(PyHamtObject), - .tp_methods = PyHamt_methods, - .tp_as_mapping = &PyHamt_as_mapping, - .tp_as_sequence = &PyHamt_as_sequence, - .tp_iter = (getiterfunc)hamt_tp_iter, - .tp_dealloc = (destructor)hamt_tp_dealloc, - .tp_getattro = PyObject_GenericGetAttr, - .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, - .tp_richcompare = hamt_tp_richcompare, - .tp_traverse = (traverseproc)hamt_tp_traverse, - .tp_clear = (inquiry)hamt_tp_clear, - .tp_new = hamt_tp_new, - .tp_weaklistoffset = offsetof(PyHamtObject, h_weakreflist), - .tp_hash = PyObject_HashNotImplemented, -}; - - -/////////////////////////////////// Tree Node Types - - -PyTypeObject _PyHamt_ArrayNode_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "hamt_array_node", - sizeof(PyHamtNode_Array), - 0, - .tp_dealloc = (destructor)hamt_node_array_dealloc, - .tp_getattro = PyObject_GenericGetAttr, - .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, - .tp_traverse = (traverseproc)hamt_node_array_traverse, - .tp_free = PyObject_GC_Del, - .tp_hash = PyObject_HashNotImplemented, -}; - -PyTypeObject _PyHamt_BitmapNode_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "hamt_bitmap_node", - sizeof(PyHamtNode_Bitmap) - sizeof(PyObject *), - sizeof(PyObject *), - .tp_dealloc = (destructor)hamt_node_bitmap_dealloc, - .tp_getattro = PyObject_GenericGetAttr, - .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, - .tp_traverse = (traverseproc)hamt_node_bitmap_traverse, - .tp_free = PyObject_GC_Del, - .tp_hash = PyObject_HashNotImplemented, -}; - -PyTypeObject _PyHamt_CollisionNode_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "hamt_collision_node", - sizeof(PyHamtNode_Collision) - sizeof(PyObject *), - sizeof(PyObject *), - .tp_dealloc = (destructor)hamt_node_collision_dealloc, - .tp_getattro = PyObject_GenericGetAttr, - .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, - .tp_traverse = (traverseproc)hamt_node_collision_traverse, - .tp_free = PyObject_GC_Del, - .tp_hash = PyObject_HashNotImplemented, -}; - - -int -_PyHamt_Init(void) -{ - if ((PyType_Ready(&_PyHamt_Type) < 0) || - (PyType_Ready(&_PyHamt_ArrayNode_Type) < 0) || - (PyType_Ready(&_PyHamt_BitmapNode_Type) < 0) || - (PyType_Ready(&_PyHamt_CollisionNode_Type) < 0) || - (PyType_Ready(&_PyHamtKeys_Type) < 0) || - (PyType_Ready(&_PyHamtValues_Type) < 0) || - (PyType_Ready(&_PyHamtItems_Type) < 0)) - { - return 0; - } - - return 1; -} - -void -_PyHamt_Fini(void) -{ - Py_CLEAR(_empty_hamt); - Py_CLEAR(_empty_bitmap_node); -} diff --git a/contrib/tools/python3/src/Python/hashtable.c b/contrib/tools/python3/src/Python/hashtable.c deleted file mode 100644 index 09501de199b..00000000000 --- a/contrib/tools/python3/src/Python/hashtable.c +++ /dev/null @@ -1,417 +0,0 @@ -/* The implementation of the hash table (_Py_hashtable_t) is based on the - cfuhash project: - http://sourceforge.net/projects/libcfu/ - - Copyright of cfuhash: - ---------------------------------- - Creation date: 2005-06-24 21:22:40 - Authors: Don - Change log: - - Copyright (c) 2005 Don Owens - All rights reserved. - - This code is released under the BSD license: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - - * Neither the name of the author nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - OF THE POSSIBILITY OF SUCH DAMAGE. - ---------------------------------- -*/ - -#include "Python.h" -#include "pycore_hashtable.h" - -#define HASHTABLE_MIN_SIZE 16 -#define HASHTABLE_HIGH 0.50 -#define HASHTABLE_LOW 0.10 -#define HASHTABLE_REHASH_FACTOR 2.0 / (HASHTABLE_LOW + HASHTABLE_HIGH) - -#define BUCKETS_HEAD(SLIST) \ - ((_Py_hashtable_entry_t *)_Py_SLIST_HEAD(&(SLIST))) -#define TABLE_HEAD(HT, BUCKET) \ - ((_Py_hashtable_entry_t *)_Py_SLIST_HEAD(&(HT)->buckets[BUCKET])) -#define ENTRY_NEXT(ENTRY) \ - ((_Py_hashtable_entry_t *)_Py_SLIST_ITEM_NEXT(ENTRY)) - -/* Forward declaration */ -static int hashtable_rehash(_Py_hashtable_t *ht); - -static void -_Py_slist_init(_Py_slist_t *list) -{ - list->head = NULL; -} - - -static void -_Py_slist_prepend(_Py_slist_t *list, _Py_slist_item_t *item) -{ - item->next = list->head; - list->head = item; -} - - -static void -_Py_slist_remove(_Py_slist_t *list, _Py_slist_item_t *previous, - _Py_slist_item_t *item) -{ - if (previous != NULL) - previous->next = item->next; - else - list->head = item->next; -} - - -Py_uhash_t -_Py_hashtable_hash_ptr(const void *key) -{ - return (Py_uhash_t)_Py_HashPointerRaw(key); -} - - -int -_Py_hashtable_compare_direct(const void *key1, const void *key2) -{ - return (key1 == key2); -} - - -/* makes sure the real size of the buckets array is a power of 2 */ -static size_t -round_size(size_t s) -{ - size_t i; - if (s < HASHTABLE_MIN_SIZE) - return HASHTABLE_MIN_SIZE; - i = 1; - while (i < s) - i <<= 1; - return i; -} - - -size_t -_Py_hashtable_size(const _Py_hashtable_t *ht) -{ - size_t size = sizeof(_Py_hashtable_t); - /* buckets */ - size += ht->nbuckets * sizeof(_Py_hashtable_entry_t *); - /* entries */ - size += ht->nentries * sizeof(_Py_hashtable_entry_t); - return size; -} - - -_Py_hashtable_entry_t * -_Py_hashtable_get_entry_generic(_Py_hashtable_t *ht, const void *key) -{ - Py_uhash_t key_hash = ht->hash_func(key); - size_t index = key_hash & (ht->nbuckets - 1); - _Py_hashtable_entry_t *entry = TABLE_HEAD(ht, index); - while (1) { - if (entry == NULL) { - return NULL; - } - if (entry->key_hash == key_hash && ht->compare_func(key, entry->key)) { - break; - } - entry = ENTRY_NEXT(entry); - } - return entry; -} - - -// Specialized for: -// hash_func == _Py_hashtable_hash_ptr -// compare_func == _Py_hashtable_compare_direct -static _Py_hashtable_entry_t * -_Py_hashtable_get_entry_ptr(_Py_hashtable_t *ht, const void *key) -{ - Py_uhash_t key_hash = _Py_hashtable_hash_ptr(key); - size_t index = key_hash & (ht->nbuckets - 1); - _Py_hashtable_entry_t *entry = TABLE_HEAD(ht, index); - while (1) { - if (entry == NULL) { - return NULL; - } - // Compare directly keys (ignore entry->key_hash) - if (entry->key == key) { - break; - } - entry = ENTRY_NEXT(entry); - } - return entry; -} - - -void* -_Py_hashtable_steal(_Py_hashtable_t *ht, const void *key) -{ - Py_uhash_t key_hash = ht->hash_func(key); - size_t index = key_hash & (ht->nbuckets - 1); - - _Py_hashtable_entry_t *entry = TABLE_HEAD(ht, index); - _Py_hashtable_entry_t *previous = NULL; - while (1) { - if (entry == NULL) { - // not found - return NULL; - } - if (entry->key_hash == key_hash && ht->compare_func(key, entry->key)) { - break; - } - previous = entry; - entry = ENTRY_NEXT(entry); - } - - _Py_slist_remove(&ht->buckets[index], (_Py_slist_item_t *)previous, - (_Py_slist_item_t *)entry); - ht->nentries--; - - void *value = entry->value; - ht->alloc.free(entry); - - if ((float)ht->nentries / (float)ht->nbuckets < HASHTABLE_LOW) { - // Ignore failure: error cannot be reported to the caller - hashtable_rehash(ht); - } - return value; -} - - -int -_Py_hashtable_set(_Py_hashtable_t *ht, const void *key, void *value) -{ - _Py_hashtable_entry_t *entry; - -#ifndef NDEBUG - /* Don't write the assertion on a single line because it is interesting - to know the duplicated entry if the assertion failed. The entry can - be read using a debugger. */ - entry = ht->get_entry_func(ht, key); - assert(entry == NULL); -#endif - - - entry = ht->alloc.malloc(sizeof(_Py_hashtable_entry_t)); - if (entry == NULL) { - /* memory allocation failed */ - return -1; - } - - entry->key_hash = ht->hash_func(key); - entry->key = (void *)key; - entry->value = value; - - ht->nentries++; - if ((float)ht->nentries / (float)ht->nbuckets > HASHTABLE_HIGH) { - if (hashtable_rehash(ht) < 0) { - ht->nentries--; - ht->alloc.free(entry); - return -1; - } - } - - size_t index = entry->key_hash & (ht->nbuckets - 1); - _Py_slist_prepend(&ht->buckets[index], (_Py_slist_item_t*)entry); - return 0; -} - - -void* -_Py_hashtable_get(_Py_hashtable_t *ht, const void *key) -{ - _Py_hashtable_entry_t *entry = ht->get_entry_func(ht, key); - if (entry != NULL) { - return entry->value; - } - else { - return NULL; - } -} - - -int -_Py_hashtable_foreach(_Py_hashtable_t *ht, - _Py_hashtable_foreach_func func, - void *user_data) -{ - for (size_t hv = 0; hv < ht->nbuckets; hv++) { - _Py_hashtable_entry_t *entry = TABLE_HEAD(ht, hv); - while (entry != NULL) { - int res = func(ht, entry->key, entry->value, user_data); - if (res) { - return res; - } - entry = ENTRY_NEXT(entry); - } - } - return 0; -} - - -static int -hashtable_rehash(_Py_hashtable_t *ht) -{ - size_t new_size = round_size((size_t)(ht->nentries * HASHTABLE_REHASH_FACTOR)); - if (new_size == ht->nbuckets) { - return 0; - } - - size_t buckets_size = new_size * sizeof(ht->buckets[0]); - _Py_slist_t *new_buckets = ht->alloc.malloc(buckets_size); - if (new_buckets == NULL) { - /* memory allocation failed */ - return -1; - } - memset(new_buckets, 0, buckets_size); - - for (size_t bucket = 0; bucket < ht->nbuckets; bucket++) { - _Py_hashtable_entry_t *entry = BUCKETS_HEAD(ht->buckets[bucket]); - while (entry != NULL) { - assert(ht->hash_func(entry->key) == entry->key_hash); - _Py_hashtable_entry_t *next = ENTRY_NEXT(entry); - size_t entry_index = entry->key_hash & (new_size - 1); - - _Py_slist_prepend(&new_buckets[entry_index], (_Py_slist_item_t*)entry); - - entry = next; - } - } - - ht->alloc.free(ht->buckets); - ht->nbuckets = new_size; - ht->buckets = new_buckets; - return 0; -} - - -_Py_hashtable_t * -_Py_hashtable_new_full(_Py_hashtable_hash_func hash_func, - _Py_hashtable_compare_func compare_func, - _Py_hashtable_destroy_func key_destroy_func, - _Py_hashtable_destroy_func value_destroy_func, - _Py_hashtable_allocator_t *allocator) -{ - _Py_hashtable_allocator_t alloc; - if (allocator == NULL) { - alloc.malloc = PyMem_Malloc; - alloc.free = PyMem_Free; - } - else { - alloc = *allocator; - } - - _Py_hashtable_t *ht = (_Py_hashtable_t *)alloc.malloc(sizeof(_Py_hashtable_t)); - if (ht == NULL) { - return ht; - } - - ht->nbuckets = HASHTABLE_MIN_SIZE; - ht->nentries = 0; - - size_t buckets_size = ht->nbuckets * sizeof(ht->buckets[0]); - ht->buckets = alloc.malloc(buckets_size); - if (ht->buckets == NULL) { - alloc.free(ht); - return NULL; - } - memset(ht->buckets, 0, buckets_size); - - ht->get_entry_func = _Py_hashtable_get_entry_generic; - ht->hash_func = hash_func; - ht->compare_func = compare_func; - ht->key_destroy_func = key_destroy_func; - ht->value_destroy_func = value_destroy_func; - ht->alloc = alloc; - if (ht->hash_func == _Py_hashtable_hash_ptr - && ht->compare_func == _Py_hashtable_compare_direct) - { - ht->get_entry_func = _Py_hashtable_get_entry_ptr; - } - return ht; -} - - -_Py_hashtable_t * -_Py_hashtable_new(_Py_hashtable_hash_func hash_func, - _Py_hashtable_compare_func compare_func) -{ - return _Py_hashtable_new_full(hash_func, compare_func, - NULL, NULL, NULL); -} - - -static void -_Py_hashtable_destroy_entry(_Py_hashtable_t *ht, _Py_hashtable_entry_t *entry) -{ - if (ht->key_destroy_func) { - ht->key_destroy_func(entry->key); - } - if (ht->value_destroy_func) { - ht->value_destroy_func(entry->value); - } - ht->alloc.free(entry); -} - - -void -_Py_hashtable_clear(_Py_hashtable_t *ht) -{ - for (size_t i=0; i < ht->nbuckets; i++) { - _Py_hashtable_entry_t *entry = TABLE_HEAD(ht, i); - while (entry != NULL) { - _Py_hashtable_entry_t *next = ENTRY_NEXT(entry); - _Py_hashtable_destroy_entry(ht, entry); - entry = next; - } - _Py_slist_init(&ht->buckets[i]); - } - ht->nentries = 0; - // Ignore failure: clear function is not expected to fail - // because of a memory allocation failure. - (void)hashtable_rehash(ht); -} - - -void -_Py_hashtable_destroy(_Py_hashtable_t *ht) -{ - for (size_t i = 0; i < ht->nbuckets; i++) { - _Py_hashtable_entry_t *entry = TABLE_HEAD(ht, i); - while (entry) { - _Py_hashtable_entry_t *entry_next = ENTRY_NEXT(entry); - _Py_hashtable_destroy_entry(ht, entry); - entry = entry_next; - } - } - - ht->alloc.free(ht->buckets); - ht->alloc.free(ht); -} diff --git a/contrib/tools/python3/src/Python/import.c b/contrib/tools/python3/src/Python/import.c deleted file mode 100644 index bd33fa184ab..00000000000 --- a/contrib/tools/python3/src/Python/import.c +++ /dev/null @@ -1,2301 +0,0 @@ -/* Module definition and import implementation */ - -#include "Python.h" - -#include "pycore_import.h" // _PyImport_BootstrapImp() -#include "pycore_initconfig.h" -#include "pycore_pyerrors.h" -#include "pycore_pyhash.h" -#include "pycore_pylifecycle.h" -#include "pycore_pymem.h" // _PyMem_SetDefaultAllocator() -#include "pycore_interp.h" // _PyInterpreterState_ClearModules() -#include "pycore_pystate.h" // _PyInterpreterState_GET() -#include "pycore_sysmodule.h" -#include "errcode.h" -#include "marshal.h" -#include "code.h" -#include "importdl.h" -#include "pydtrace.h" - -#ifdef HAVE_FCNTL_H -#include <fcntl.h> -#endif -#ifdef __cplusplus -extern "C" { -#endif - -#define CACHEDIR "__pycache__" - -/* Forward references */ -static PyObject *import_add_module(PyThreadState *tstate, PyObject *name); - -/* See _PyImport_FixupExtensionObject() below */ -static PyObject *extensions = NULL; - -/* This table is defined in config.c: */ -extern struct _inittab _PyImport_Inittab[]; - -struct _inittab *PyImport_Inittab = _PyImport_Inittab; -static struct _inittab *inittab_copy = NULL; - -_Py_IDENTIFIER(__path__); -_Py_IDENTIFIER(__spec__); - -/*[clinic input] -module _imp -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=9c332475d8686284]*/ - -#include "clinic/import.c.h" - -/* Initialize things */ - -PyStatus -_PyImportZip_Init(PyThreadState *tstate) -{ - PyObject *path_hooks, *zipimport; - int err = 0; - - path_hooks = PySys_GetObject("path_hooks"); - if (path_hooks == NULL) { - _PyErr_SetString(tstate, PyExc_RuntimeError, - "unable to get sys.path_hooks"); - goto error; - } - - int verbose = _PyInterpreterState_GetConfig(tstate->interp)->verbose; - if (verbose) { - PySys_WriteStderr("# installing zipimport hook\n"); - } - - zipimport = PyImport_ImportModule("zipimport"); - if (zipimport == NULL) { - _PyErr_Clear(tstate); /* No zip import module -- okay */ - if (verbose) { - PySys_WriteStderr("# can't import zipimport\n"); - } - } - else { - _Py_IDENTIFIER(zipimporter); - PyObject *zipimporter = _PyObject_GetAttrId(zipimport, - &PyId_zipimporter); - Py_DECREF(zipimport); - if (zipimporter == NULL) { - _PyErr_Clear(tstate); /* No zipimporter object -- okay */ - if (verbose) { - PySys_WriteStderr("# can't import zipimport.zipimporter\n"); - } - } - else { - /* sys.path_hooks.insert(0, zipimporter) */ - err = PyList_Insert(path_hooks, 0, zipimporter); - Py_DECREF(zipimporter); - if (err < 0) { - goto error; - } - if (verbose) { - PySys_WriteStderr("# installed zipimport hook\n"); - } - } - } - - return _PyStatus_OK(); - - error: - PyErr_Print(); - return _PyStatus_ERR("initializing zipimport failed"); -} - -/* Locking primitives to prevent parallel imports of the same module - in different threads to return with a partially loaded module. - These calls are serialized by the global interpreter lock. */ - -static PyThread_type_lock import_lock = NULL; -static unsigned long import_lock_thread = PYTHREAD_INVALID_THREAD_ID; -static int import_lock_level = 0; - -void -_PyImport_AcquireLock(void) -{ - unsigned long me = PyThread_get_thread_ident(); - if (me == PYTHREAD_INVALID_THREAD_ID) - return; /* Too bad */ - if (import_lock == NULL) { - import_lock = PyThread_allocate_lock(); - if (import_lock == NULL) - return; /* Nothing much we can do. */ - } - if (import_lock_thread == me) { - import_lock_level++; - return; - } - if (import_lock_thread != PYTHREAD_INVALID_THREAD_ID || - !PyThread_acquire_lock(import_lock, 0)) - { - PyThreadState *tstate = PyEval_SaveThread(); - PyThread_acquire_lock(import_lock, WAIT_LOCK); - PyEval_RestoreThread(tstate); - } - assert(import_lock_level == 0); - import_lock_thread = me; - import_lock_level = 1; -} - -int -_PyImport_ReleaseLock(void) -{ - unsigned long me = PyThread_get_thread_ident(); - if (me == PYTHREAD_INVALID_THREAD_ID || import_lock == NULL) - return 0; /* Too bad */ - if (import_lock_thread != me) - return -1; - import_lock_level--; - assert(import_lock_level >= 0); - if (import_lock_level == 0) { - import_lock_thread = PYTHREAD_INVALID_THREAD_ID; - PyThread_release_lock(import_lock); - } - return 1; -} - -#ifdef HAVE_FORK -/* This function is called from PyOS_AfterFork_Child() to ensure that newly - created child processes do not share locks with the parent. - We now acquire the import lock around fork() calls but on some platforms - (Solaris 9 and earlier? see isue7242) that still left us with problems. */ -PyStatus -_PyImport_ReInitLock(void) -{ - if (import_lock != NULL) { - if (_PyThread_at_fork_reinit(&import_lock) < 0) { - return _PyStatus_ERR("failed to create a new lock"); - } - } - - if (import_lock_level > 1) { - /* Forked as a side effect of import */ - unsigned long me = PyThread_get_thread_ident(); - PyThread_acquire_lock(import_lock, WAIT_LOCK); - import_lock_thread = me; - import_lock_level--; - } else { - import_lock_thread = PYTHREAD_INVALID_THREAD_ID; - import_lock_level = 0; - } - return _PyStatus_OK(); -} -#endif - -/*[clinic input] -_imp.lock_held - -Return True if the import lock is currently held, else False. - -On platforms without threads, return False. -[clinic start generated code]*/ - -static PyObject * -_imp_lock_held_impl(PyObject *module) -/*[clinic end generated code: output=8b89384b5e1963fc input=9b088f9b217d9bdf]*/ -{ - return PyBool_FromLong(import_lock_thread != PYTHREAD_INVALID_THREAD_ID); -} - -/*[clinic input] -_imp.acquire_lock - -Acquires the interpreter's import lock for the current thread. - -This lock should be used by import hooks to ensure thread-safety when importing -modules. On platforms without threads, this function does nothing. -[clinic start generated code]*/ - -static PyObject * -_imp_acquire_lock_impl(PyObject *module) -/*[clinic end generated code: output=1aff58cb0ee1b026 input=4a2d4381866d5fdc]*/ -{ - _PyImport_AcquireLock(); - Py_RETURN_NONE; -} - -/*[clinic input] -_imp.release_lock - -Release the interpreter's import lock. - -On platforms without threads, this function does nothing. -[clinic start generated code]*/ - -static PyObject * -_imp_release_lock_impl(PyObject *module) -/*[clinic end generated code: output=7faab6d0be178b0a input=934fb11516dd778b]*/ -{ - if (_PyImport_ReleaseLock() < 0) { - PyErr_SetString(PyExc_RuntimeError, - "not holding the import lock"); - return NULL; - } - Py_RETURN_NONE; -} - -void -_PyImport_Fini(void) -{ - Py_CLEAR(extensions); - if (import_lock != NULL) { - PyThread_free_lock(import_lock); - import_lock = NULL; - } -} - -void -_PyImport_Fini2(void) -{ - /* Use the same memory allocator than PyImport_ExtendInittab(). */ - PyMemAllocatorEx old_alloc; - _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - - // Reset PyImport_Inittab - PyImport_Inittab = _PyImport_Inittab; - - /* Free memory allocated by PyImport_ExtendInittab() */ - PyMem_RawFree(inittab_copy); - inittab_copy = NULL; - - PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); -} - -/* Helper for sys */ - -PyObject * -PyImport_GetModuleDict(void) -{ - PyInterpreterState *interp = _PyInterpreterState_GET(); - if (interp->modules == NULL) { - Py_FatalError("interpreter has no modules dictionary"); - } - return interp->modules; -} - -/* In some corner cases it is important to be sure that the import - machinery has been initialized (or not cleaned up yet). For - example, see issue #4236 and PyModule_Create2(). */ - -int -_PyImport_IsInitialized(PyInterpreterState *interp) -{ - if (interp->modules == NULL) - return 0; - return 1; -} - -PyObject * -_PyImport_GetModuleId(struct _Py_Identifier *nameid) -{ - PyObject *name = _PyUnicode_FromId(nameid); /* borrowed */ - if (name == NULL) { - return NULL; - } - return PyImport_GetModule(name); -} - -int -_PyImport_SetModule(PyObject *name, PyObject *m) -{ - PyInterpreterState *interp = _PyInterpreterState_GET(); - PyObject *modules = interp->modules; - return PyObject_SetItem(modules, name, m); -} - -int -_PyImport_SetModuleString(const char *name, PyObject *m) -{ - PyInterpreterState *interp = _PyInterpreterState_GET(); - PyObject *modules = interp->modules; - return PyMapping_SetItemString(modules, name, m); -} - -static PyObject * -import_get_module(PyThreadState *tstate, PyObject *name) -{ - PyObject *modules = tstate->interp->modules; - if (modules == NULL) { - _PyErr_SetString(tstate, PyExc_RuntimeError, - "unable to get sys.modules"); - return NULL; - } - - PyObject *m; - Py_INCREF(modules); - if (PyDict_CheckExact(modules)) { - m = PyDict_GetItemWithError(modules, name); /* borrowed */ - Py_XINCREF(m); - } - else { - m = PyObject_GetItem(modules, name); - if (m == NULL && _PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { - _PyErr_Clear(tstate); - } - } - Py_DECREF(modules); - return m; -} - - -static int -import_ensure_initialized(PyInterpreterState *interp, PyObject *mod, PyObject *name) -{ - PyObject *spec; - - _Py_IDENTIFIER(_lock_unlock_module); - - /* Optimization: only call _bootstrap._lock_unlock_module() if - __spec__._initializing is true. - NOTE: because of this, initializing must be set *before* - stuffing the new module in sys.modules. - */ - spec = _PyObject_GetAttrId(mod, &PyId___spec__); - int busy = _PyModuleSpec_IsInitializing(spec); - Py_XDECREF(spec); - if (busy) { - /* Wait until module is done importing. */ - PyObject *value = _PyObject_CallMethodIdOneArg( - interp->importlib, &PyId__lock_unlock_module, name); - if (value == NULL) { - return -1; - } - Py_DECREF(value); - } - return 0; -} - - -/* Helper for pythonrun.c -- return magic number and tag. */ - -long -PyImport_GetMagicNumber(void) -{ - long res; - PyInterpreterState *interp = _PyInterpreterState_GET(); - PyObject *external, *pyc_magic; - - external = PyObject_GetAttrString(interp->importlib, "_bootstrap_external"); - if (external == NULL) - return -1; - pyc_magic = PyObject_GetAttrString(external, "_RAW_MAGIC_NUMBER"); - Py_DECREF(external); - if (pyc_magic == NULL) - return -1; - res = PyLong_AsLong(pyc_magic); - Py_DECREF(pyc_magic); - return res; -} - - -extern const char * _PySys_ImplCacheTag; - -const char * -PyImport_GetMagicTag(void) -{ - return _PySys_ImplCacheTag; -} - - -/* Magic for extension modules (built-in as well as dynamically - loaded). To prevent initializing an extension module more than - once, we keep a static dictionary 'extensions' keyed by the tuple - (module name, module name) (for built-in modules) or by - (filename, module name) (for dynamically loaded modules), containing these - modules. A copy of the module's dictionary is stored by calling - _PyImport_FixupExtensionObject() immediately after the module initialization - function succeeds. A copy can be retrieved from there by calling - import_find_extension(). - - Modules which do support multiple initialization set their m_size - field to a non-negative number (indicating the size of the - module-specific state). They are still recorded in the extensions - dictionary, to avoid loading shared libraries twice. -*/ - -int -_PyImport_FixupExtensionObject(PyObject *mod, PyObject *name, - PyObject *filename, PyObject *modules) -{ - if (mod == NULL || !PyModule_Check(mod)) { - PyErr_BadInternalCall(); - return -1; - } - - struct PyModuleDef *def = PyModule_GetDef(mod); - if (!def) { - PyErr_BadInternalCall(); - return -1; - } - - PyThreadState *tstate = _PyThreadState_GET(); - if (PyObject_SetItem(modules, name, mod) < 0) { - return -1; - } - if (_PyState_AddModule(tstate, mod, def) < 0) { - PyMapping_DelItem(modules, name); - return -1; - } - - // bpo-44050: Extensions and def->m_base.m_copy can be updated - // when the extension module doesn't support sub-interpreters. - if (_Py_IsMainInterpreter(tstate->interp) || def->m_size == -1) { - if (def->m_size == -1) { - if (def->m_base.m_copy) { - /* Somebody already imported the module, - likely under a different name. - XXX this should really not happen. */ - Py_CLEAR(def->m_base.m_copy); - } - PyObject *dict = PyModule_GetDict(mod); - if (dict == NULL) { - return -1; - } - def->m_base.m_copy = PyDict_Copy(dict); - if (def->m_base.m_copy == NULL) { - return -1; - } - } - - if (extensions == NULL) { - extensions = PyDict_New(); - if (extensions == NULL) { - return -1; - } - } - - PyObject *key = PyTuple_Pack(2, filename, name); - if (key == NULL) { - return -1; - } - int res = PyDict_SetItem(extensions, key, (PyObject *)def); - Py_DECREF(key); - if (res < 0) { - return -1; - } - } - - return 0; -} - -int -_PyImport_FixupBuiltin(PyObject *mod, const char *name, PyObject *modules) -{ - int res; - PyObject *nameobj; - nameobj = PyUnicode_InternFromString(name); - if (nameobj == NULL) - return -1; - res = _PyImport_FixupExtensionObject(mod, nameobj, nameobj, modules); - Py_DECREF(nameobj); - return res; -} - -static PyObject * -import_find_extension(PyThreadState *tstate, PyObject *name, - PyObject *filename) -{ - if (extensions == NULL) { - return NULL; - } - - PyObject *key = PyTuple_Pack(2, filename, name); - if (key == NULL) { - return NULL; - } - PyModuleDef* def = (PyModuleDef *)PyDict_GetItemWithError(extensions, key); - Py_DECREF(key); - if (def == NULL) { - return NULL; - } - - PyObject *mod, *mdict; - PyObject *modules = tstate->interp->modules; - - if (def->m_size == -1) { - /* Module does not support repeated initialization */ - if (def->m_base.m_copy == NULL) - return NULL; - mod = import_add_module(tstate, name); - if (mod == NULL) - return NULL; - mdict = PyModule_GetDict(mod); - if (mdict == NULL) { - Py_DECREF(mod); - return NULL; - } - if (PyDict_Update(mdict, def->m_base.m_copy)) { - Py_DECREF(mod); - return NULL; - } - } - else { - if (def->m_base.m_init == NULL) - return NULL; - mod = def->m_base.m_init(); - if (mod == NULL) - return NULL; - if (PyObject_SetItem(modules, name, mod) == -1) { - Py_DECREF(mod); - return NULL; - } - } - if (_PyState_AddModule(tstate, mod, def) < 0) { - PyMapping_DelItem(modules, name); - Py_DECREF(mod); - return NULL; - } - - int verbose = _PyInterpreterState_GetConfig(tstate->interp)->verbose; - if (verbose) { - PySys_FormatStderr("import %U # previously loaded (%R)\n", - name, filename); - } - return mod; -} - -PyObject * -_PyImport_FindExtensionObject(PyObject *name, PyObject *filename) -{ - PyThreadState *tstate = _PyThreadState_GET(); - PyObject *mod = import_find_extension(tstate, name, filename); - if (mod) { - PyObject *ref = PyWeakref_NewRef(mod, NULL); - Py_DECREF(mod); - if (ref == NULL) { - return NULL; - } - mod = PyWeakref_GetObject(ref); - Py_DECREF(ref); - } - return mod; /* borrowed reference */ -} - - -/* Get the module object corresponding to a module name. - First check the modules dictionary if there's one there, - if not, create a new one and insert it in the modules dictionary. */ - -static PyObject * -import_add_module(PyThreadState *tstate, PyObject *name) -{ - PyObject *modules = tstate->interp->modules; - if (modules == NULL) { - _PyErr_SetString(tstate, PyExc_RuntimeError, - "no import module dictionary"); - return NULL; - } - - PyObject *m; - if (PyDict_CheckExact(modules)) { - m = PyDict_GetItemWithError(modules, name); - Py_XINCREF(m); - } - else { - m = PyObject_GetItem(modules, name); - // For backward-compatibility we copy the behavior - // of PyDict_GetItemWithError(). - if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { - _PyErr_Clear(tstate); - } - } - if (_PyErr_Occurred(tstate)) { - return NULL; - } - if (m != NULL && PyModule_Check(m)) { - return m; - } - Py_XDECREF(m); - m = PyModule_NewObject(name); - if (m == NULL) - return NULL; - if (PyObject_SetItem(modules, name, m) != 0) { - Py_DECREF(m); - return NULL; - } - - return m; -} - -PyObject * -PyImport_AddModuleObject(PyObject *name) -{ - PyThreadState *tstate = _PyThreadState_GET(); - PyObject *mod = import_add_module(tstate, name); - if (mod) { - PyObject *ref = PyWeakref_NewRef(mod, NULL); - Py_DECREF(mod); - if (ref == NULL) { - return NULL; - } - mod = PyWeakref_GetObject(ref); - Py_DECREF(ref); - } - return mod; /* borrowed reference */ -} - - -PyObject * -PyImport_AddModule(const char *name) -{ - PyObject *nameobj = PyUnicode_FromString(name); - if (nameobj == NULL) { - return NULL; - } - PyObject *module = PyImport_AddModuleObject(nameobj); - Py_DECREF(nameobj); - return module; -} - - -/* Remove name from sys.modules, if it's there. - * Can be called with an exception raised. - * If fail to remove name a new exception will be chained with the old - * exception, otherwise the old exception is preserved. - */ -static void -remove_module(PyThreadState *tstate, PyObject *name) -{ - PyObject *type, *value, *traceback; - _PyErr_Fetch(tstate, &type, &value, &traceback); - - PyObject *modules = tstate->interp->modules; - if (PyDict_CheckExact(modules)) { - PyObject *mod = _PyDict_Pop(modules, name, Py_None); - Py_XDECREF(mod); - } - else if (PyMapping_DelItem(modules, name) < 0) { - if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { - _PyErr_Clear(tstate); - } - } - - _PyErr_ChainExceptions(type, value, traceback); -} - - -/* Execute a code object in a module and return the module object - * WITH INCREMENTED REFERENCE COUNT. If an error occurs, name is - * removed from sys.modules, to avoid leaving damaged module objects - * in sys.modules. The caller may wish to restore the original - * module object (if any) in this case; PyImport_ReloadModule is an - * example. - * - * Note that PyImport_ExecCodeModuleWithPathnames() is the preferred, richer - * interface. The other two exist primarily for backward compatibility. - */ -PyObject * -PyImport_ExecCodeModule(const char *name, PyObject *co) -{ - return PyImport_ExecCodeModuleWithPathnames( - name, co, (char *)NULL, (char *)NULL); -} - -PyObject * -PyImport_ExecCodeModuleEx(const char *name, PyObject *co, const char *pathname) -{ - return PyImport_ExecCodeModuleWithPathnames( - name, co, pathname, (char *)NULL); -} - -PyObject * -PyImport_ExecCodeModuleWithPathnames(const char *name, PyObject *co, - const char *pathname, - const char *cpathname) -{ - PyObject *m = NULL; - PyObject *nameobj, *pathobj = NULL, *cpathobj = NULL, *external= NULL; - - nameobj = PyUnicode_FromString(name); - if (nameobj == NULL) - return NULL; - - if (cpathname != NULL) { - cpathobj = PyUnicode_DecodeFSDefault(cpathname); - if (cpathobj == NULL) - goto error; - } - else - cpathobj = NULL; - - if (pathname != NULL) { - pathobj = PyUnicode_DecodeFSDefault(pathname); - if (pathobj == NULL) - goto error; - } - else if (cpathobj != NULL) { - PyInterpreterState *interp = _PyInterpreterState_GET(); - _Py_IDENTIFIER(_get_sourcefile); - - if (interp == NULL) { - Py_FatalError("no current interpreter"); - } - - external= PyObject_GetAttrString(interp->importlib, - "_bootstrap_external"); - if (external != NULL) { - pathobj = _PyObject_CallMethodIdOneArg( - external, &PyId__get_sourcefile, cpathobj); - Py_DECREF(external); - } - if (pathobj == NULL) - PyErr_Clear(); - } - else - pathobj = NULL; - - m = PyImport_ExecCodeModuleObject(nameobj, co, pathobj, cpathobj); -error: - Py_DECREF(nameobj); - Py_XDECREF(pathobj); - Py_XDECREF(cpathobj); - return m; -} - -static PyObject * -module_dict_for_exec(PyThreadState *tstate, PyObject *name) -{ - _Py_IDENTIFIER(__builtins__); - PyObject *m, *d; - - m = import_add_module(tstate, name); - if (m == NULL) - return NULL; - /* If the module is being reloaded, we get the old module back - and re-use its dict to exec the new code. */ - d = PyModule_GetDict(m); - int r = _PyDict_ContainsId(d, &PyId___builtins__); - if (r == 0) { - r = _PyDict_SetItemId(d, &PyId___builtins__, - PyEval_GetBuiltins()); - } - if (r < 0) { - remove_module(tstate, name); - Py_DECREF(m); - return NULL; - } - - Py_INCREF(d); - Py_DECREF(m); - return d; -} - -static PyObject * -exec_code_in_module(PyThreadState *tstate, PyObject *name, - PyObject *module_dict, PyObject *code_object) -{ - PyObject *v, *m; - - v = PyEval_EvalCode(code_object, module_dict, module_dict); - if (v == NULL) { - remove_module(tstate, name); - return NULL; - } - Py_DECREF(v); - - m = import_get_module(tstate, name); - if (m == NULL && !_PyErr_Occurred(tstate)) { - _PyErr_Format(tstate, PyExc_ImportError, - "Loaded module %R not found in sys.modules", - name); - } - - return m; -} - -PyObject* -PyImport_ExecCodeModuleObject(PyObject *name, PyObject *co, PyObject *pathname, - PyObject *cpathname) -{ - PyThreadState *tstate = _PyThreadState_GET(); - PyObject *d, *external, *res; - _Py_IDENTIFIER(_fix_up_module); - - d = module_dict_for_exec(tstate, name); - if (d == NULL) { - return NULL; - } - - if (pathname == NULL) { - pathname = ((PyCodeObject *)co)->co_filename; - } - external = PyObject_GetAttrString(tstate->interp->importlib, - "_bootstrap_external"); - if (external == NULL) { - Py_DECREF(d); - return NULL; - } - res = _PyObject_CallMethodIdObjArgs(external, - &PyId__fix_up_module, - d, name, pathname, cpathname, NULL); - Py_DECREF(external); - if (res != NULL) { - Py_DECREF(res); - res = exec_code_in_module(tstate, name, d, co); - } - Py_DECREF(d); - return res; -} - - -static void -update_code_filenames(PyCodeObject *co, PyObject *oldname, PyObject *newname) -{ - PyObject *constants, *tmp; - Py_ssize_t i, n; - - if (PyUnicode_Compare(co->co_filename, oldname)) - return; - - Py_INCREF(newname); - Py_XSETREF(co->co_filename, newname); - - constants = co->co_consts; - n = PyTuple_GET_SIZE(constants); - for (i = 0; i < n; i++) { - tmp = PyTuple_GET_ITEM(constants, i); - if (PyCode_Check(tmp)) - update_code_filenames((PyCodeObject *)tmp, - oldname, newname); - } -} - -static void -update_compiled_module(PyCodeObject *co, PyObject *newname) -{ - PyObject *oldname; - - if (PyUnicode_Compare(co->co_filename, newname) == 0) - return; - - oldname = co->co_filename; - Py_INCREF(oldname); - update_code_filenames(co, oldname, newname); - Py_DECREF(oldname); -} - -/*[clinic input] -_imp._fix_co_filename - - code: object(type="PyCodeObject *", subclass_of="&PyCode_Type") - Code object to change. - - path: unicode - File path to use. - / - -Changes code.co_filename to specify the passed-in file path. -[clinic start generated code]*/ - -static PyObject * -_imp__fix_co_filename_impl(PyObject *module, PyCodeObject *code, - PyObject *path) -/*[clinic end generated code: output=1d002f100235587d input=895ba50e78b82f05]*/ - -{ - update_compiled_module(code, path); - - Py_RETURN_NONE; -} - - -/* Forward */ -static const struct _frozen * find_frozen(PyObject *); - - -/* Helper to test for built-in module */ - -static int -is_builtin(PyObject *name) -{ - int i; - for (i = 0; PyImport_Inittab[i].name != NULL; i++) { - if (_PyUnicode_EqualToASCIIString(name, PyImport_Inittab[i].name)) { - if (PyImport_Inittab[i].initfunc == NULL) - return -1; - else - return 1; - } - } - return 0; -} - - -/* Return a finder object for a sys.path/pkg.__path__ item 'p', - possibly by fetching it from the path_importer_cache dict. If it - wasn't yet cached, traverse path_hooks until a hook is found - that can handle the path item. Return None if no hook could; - this tells our caller that the path based finder could not find - a finder for this path item. Cache the result in - path_importer_cache. */ - -static PyObject * -get_path_importer(PyThreadState *tstate, PyObject *path_importer_cache, - PyObject *path_hooks, PyObject *p) -{ - PyObject *importer; - Py_ssize_t j, nhooks; - - /* These conditions are the caller's responsibility: */ - assert(PyList_Check(path_hooks)); - assert(PyDict_Check(path_importer_cache)); - - nhooks = PyList_Size(path_hooks); - if (nhooks < 0) - return NULL; /* Shouldn't happen */ - - importer = PyDict_GetItemWithError(path_importer_cache, p); - if (importer != NULL || _PyErr_Occurred(tstate)) { - Py_XINCREF(importer); - return importer; - } - - /* set path_importer_cache[p] to None to avoid recursion */ - if (PyDict_SetItem(path_importer_cache, p, Py_None) != 0) - return NULL; - - for (j = 0; j < nhooks; j++) { - PyObject *hook = PyList_GetItem(path_hooks, j); - if (hook == NULL) - return NULL; - importer = PyObject_CallOneArg(hook, p); - if (importer != NULL) - break; - - if (!_PyErr_ExceptionMatches(tstate, PyExc_ImportError)) { - return NULL; - } - _PyErr_Clear(tstate); - } - if (importer == NULL) { - Py_RETURN_NONE; - } - if (PyDict_SetItem(path_importer_cache, p, importer) < 0) { - Py_DECREF(importer); - return NULL; - } - return importer; -} - -PyObject * -PyImport_GetImporter(PyObject *path) -{ - PyThreadState *tstate = _PyThreadState_GET(); - PyObject *path_importer_cache = PySys_GetObject("path_importer_cache"); - PyObject *path_hooks = PySys_GetObject("path_hooks"); - if (path_importer_cache == NULL || path_hooks == NULL) { - return NULL; - } - return get_path_importer(tstate, path_importer_cache, path_hooks, path); -} - -static PyObject* -create_builtin(PyThreadState *tstate, PyObject *name, PyObject *spec) -{ - PyObject *mod = import_find_extension(tstate, name, name); - if (mod || _PyErr_Occurred(tstate)) { - return mod; - } - - PyObject *modules = tstate->interp->modules; - for (struct _inittab *p = PyImport_Inittab; p->name != NULL; p++) { - if (_PyUnicode_EqualToASCIIString(name, p->name)) { - if (p->initfunc == NULL) { - /* Cannot re-init internal module ("sys" or "builtins") */ - return PyImport_AddModuleObject(name); - } - - mod = (*p->initfunc)(); - if (mod == NULL) { - return NULL; - } - - if (PyObject_TypeCheck(mod, &PyModuleDef_Type)) { - return PyModule_FromDefAndSpec((PyModuleDef*)mod, spec); - } - else { - /* Remember pointer to module init function. */ - PyModuleDef *def = PyModule_GetDef(mod); - if (def == NULL) { - return NULL; - } - - def->m_base.m_init = p->initfunc; - if (_PyImport_FixupExtensionObject(mod, name, name, - modules) < 0) { - return NULL; - } - return mod; - } - } - } - - // not found - Py_RETURN_NONE; -} - - - -/*[clinic input] -_imp.create_builtin - - spec: object - / - -Create an extension module. -[clinic start generated code]*/ - -static PyObject * -_imp_create_builtin(PyObject *module, PyObject *spec) -/*[clinic end generated code: output=ace7ff22271e6f39 input=37f966f890384e47]*/ -{ - PyThreadState *tstate = _PyThreadState_GET(); - - PyObject *name = PyObject_GetAttrString(spec, "name"); - if (name == NULL) { - return NULL; - } - - PyObject *mod = create_builtin(tstate, name, spec); - Py_DECREF(name); - return mod; -} - - -/* Frozen modules */ - -static const struct _frozen * -find_frozen(PyObject *name) -{ - const struct _frozen *p; - - if (name == NULL) - return NULL; - - for (p = PyImport_FrozenModules; ; p++) { - if (p->name == NULL) - return NULL; - if (_PyUnicode_EqualToASCIIString(name, p->name)) - break; - } - return p; -} - -static PyObject * -get_frozen_object(PyObject *name) -{ - const struct _frozen *p = find_frozen(name); - int size; - - if (p == NULL) { - PyErr_Format(PyExc_ImportError, - "No such frozen object named %R", - name); - return NULL; - } - if (p->code == NULL) { - PyErr_Format(PyExc_ImportError, - "Excluded frozen object named %R", - name); - return NULL; - } - size = p->size; - if (size < 0) - size = -size; - return PyMarshal_ReadObjectFromString((const char *)p->code, size); -} - -static PyObject * -is_frozen_package(PyObject *name) -{ - const struct _frozen *p = find_frozen(name); - int size; - - if (p == NULL) { - PyErr_Format(PyExc_ImportError, - "No such frozen object named %R", - name); - return NULL; - } - - size = p->size; - - if (size < 0) - Py_RETURN_TRUE; - else - Py_RETURN_FALSE; -} - - -/* Initialize a frozen module. - Return 1 for success, 0 if the module is not found, and -1 with - an exception set if the initialization failed. - This function is also used from frozenmain.c */ - -int -PyImport_ImportFrozenModuleObject(PyObject *name) -{ - PyThreadState *tstate = _PyThreadState_GET(); - const struct _frozen *p; - PyObject *co, *m, *d; - int ispackage; - int size; - - p = find_frozen(name); - - if (p == NULL) - return 0; - if (p->code == NULL) { - _PyErr_Format(tstate, PyExc_ImportError, - "Excluded frozen object named %R", - name); - return -1; - } - size = p->size; - ispackage = (size < 0); - if (ispackage) - size = -size; - co = PyMarshal_ReadObjectFromString((const char *)p->code, size); - if (co == NULL) - return -1; - if (!PyCode_Check(co)) { - _PyErr_Format(tstate, PyExc_TypeError, - "frozen object %R is not a code object", - name); - goto err_return; - } - if (ispackage) { - /* Set __path__ to the empty list */ - PyObject *l; - int err; - m = import_add_module(tstate, name); - if (m == NULL) - goto err_return; - d = PyModule_GetDict(m); - l = PyList_New(0); - if (l == NULL) { - Py_DECREF(m); - goto err_return; - } - err = PyDict_SetItemString(d, "__path__", l); - Py_DECREF(l); - Py_DECREF(m); - if (err != 0) - goto err_return; - } - d = module_dict_for_exec(tstate, name); - if (d == NULL) { - goto err_return; - } - m = exec_code_in_module(tstate, name, d, co); - Py_DECREF(d); - if (m == NULL) { - goto err_return; - } - Py_DECREF(co); - Py_DECREF(m); - return 1; - -err_return: - Py_DECREF(co); - return -1; -} - -int -PyImport_ImportFrozenModule(const char *name) -{ - PyObject *nameobj; - int ret; - nameobj = PyUnicode_InternFromString(name); - if (nameobj == NULL) - return -1; - ret = PyImport_ImportFrozenModuleObject(nameobj); - Py_DECREF(nameobj); - return ret; -} - - -/* Import a module, either built-in, frozen, or external, and return - its module object WITH INCREMENTED REFERENCE COUNT */ - -PyObject * -PyImport_ImportModule(const char *name) -{ - PyObject *pname; - PyObject *result; - - pname = PyUnicode_FromString(name); - if (pname == NULL) - return NULL; - result = PyImport_Import(pname); - Py_DECREF(pname); - return result; -} - - -/* Import a module without blocking - * - * At first it tries to fetch the module from sys.modules. If the module was - * never loaded before it loads it with PyImport_ImportModule() unless another - * thread holds the import lock. In the latter case the function raises an - * ImportError instead of blocking. - * - * Returns the module object with incremented ref count. - */ -PyObject * -PyImport_ImportModuleNoBlock(const char *name) -{ - return PyImport_ImportModule(name); -} - - -/* Remove importlib frames from the traceback, - * except in Verbose mode. */ -static void -remove_importlib_frames(PyThreadState *tstate) -{ - const char *importlib_filename = "<frozen importlib._bootstrap>"; - const char *external_filename = "<frozen importlib._bootstrap_external>"; - const char *importer_filename = "library/python/runtime_py3/importer.pxi"; - const char *remove_frames = "_call_with_frames_removed"; - int always_trim = 0; - int in_importlib = 0; - PyObject *exception, *value, *base_tb, *tb; - PyObject **prev_link, **outer_link = NULL; - - /* Synopsis: if it's an ImportError, we trim all importlib chunks - from the traceback. We always trim chunks - which end with a call to "_call_with_frames_removed". */ - - _PyErr_Fetch(tstate, &exception, &value, &base_tb); - if (!exception || _PyInterpreterState_GetConfig(tstate->interp)->verbose) { - goto done; - } - - if (PyType_IsSubtype((PyTypeObject *) exception, - (PyTypeObject *) PyExc_ImportError)) - always_trim = 1; - - prev_link = &base_tb; - tb = base_tb; - while (tb != NULL) { - PyTracebackObject *traceback = (PyTracebackObject *)tb; - PyObject *next = (PyObject *) traceback->tb_next; - PyFrameObject *frame = traceback->tb_frame; - PyCodeObject *code = PyFrame_GetCode(frame); - int now_in_importlib; - - assert(PyTraceBack_Check(tb)); - now_in_importlib = _PyUnicode_EqualToASCIIString(code->co_filename, importlib_filename) || - _PyUnicode_EqualToASCIIString(code->co_filename, external_filename) || - _PyUnicode_EqualToASCIIString(code->co_filename, importer_filename); - if (now_in_importlib && !in_importlib) { - /* This is the link to this chunk of importlib tracebacks */ - outer_link = prev_link; - } - in_importlib = now_in_importlib; - - if (in_importlib && - (always_trim || - _PyUnicode_EqualToASCIIString(code->co_name, remove_frames))) { - Py_XINCREF(next); - Py_XSETREF(*outer_link, next); - prev_link = outer_link; - } - else { - prev_link = (PyObject **) &traceback->tb_next; - } - Py_DECREF(code); - tb = next; - } -done: - _PyErr_Restore(tstate, exception, value, base_tb); -} - - -static PyObject * -resolve_name(PyThreadState *tstate, PyObject *name, PyObject *globals, int level) -{ - _Py_IDENTIFIER(__package__); - _Py_IDENTIFIER(__name__); - _Py_IDENTIFIER(parent); - PyObject *abs_name; - PyObject *package = NULL; - PyObject *spec; - Py_ssize_t last_dot; - PyObject *base; - int level_up; - - if (globals == NULL) { - _PyErr_SetString(tstate, PyExc_KeyError, "'__name__' not in globals"); - goto error; - } - if (!PyDict_Check(globals)) { - _PyErr_SetString(tstate, PyExc_TypeError, "globals must be a dict"); - goto error; - } - package = _PyDict_GetItemIdWithError(globals, &PyId___package__); - if (package == Py_None) { - package = NULL; - } - else if (package == NULL && _PyErr_Occurred(tstate)) { - goto error; - } - spec = _PyDict_GetItemIdWithError(globals, &PyId___spec__); - if (spec == NULL && _PyErr_Occurred(tstate)) { - goto error; - } - - if (package != NULL) { - Py_INCREF(package); - if (!PyUnicode_Check(package)) { - _PyErr_SetString(tstate, PyExc_TypeError, - "package must be a string"); - goto error; - } - else if (spec != NULL && spec != Py_None) { - int equal; - PyObject *parent = _PyObject_GetAttrId(spec, &PyId_parent); - if (parent == NULL) { - goto error; - } - - equal = PyObject_RichCompareBool(package, parent, Py_EQ); - Py_DECREF(parent); - if (equal < 0) { - goto error; - } - else if (equal == 0) { - if (PyErr_WarnEx(PyExc_ImportWarning, - "__package__ != __spec__.parent", 1) < 0) { - goto error; - } - } - } - } - else if (spec != NULL && spec != Py_None) { - package = _PyObject_GetAttrId(spec, &PyId_parent); - if (package == NULL) { - goto error; - } - else if (!PyUnicode_Check(package)) { - _PyErr_SetString(tstate, PyExc_TypeError, - "__spec__.parent must be a string"); - goto error; - } - } - else { - if (PyErr_WarnEx(PyExc_ImportWarning, - "can't resolve package from __spec__ or __package__, " - "falling back on __name__ and __path__", 1) < 0) { - goto error; - } - - package = _PyDict_GetItemIdWithError(globals, &PyId___name__); - if (package == NULL) { - if (!_PyErr_Occurred(tstate)) { - _PyErr_SetString(tstate, PyExc_KeyError, - "'__name__' not in globals"); - } - goto error; - } - - Py_INCREF(package); - if (!PyUnicode_Check(package)) { - _PyErr_SetString(tstate, PyExc_TypeError, - "__name__ must be a string"); - goto error; - } - - int haspath = _PyDict_ContainsId(globals, &PyId___path__); - if (haspath < 0) { - goto error; - } - if (!haspath) { - Py_ssize_t dot; - - if (PyUnicode_READY(package) < 0) { - goto error; - } - - dot = PyUnicode_FindChar(package, '.', - 0, PyUnicode_GET_LENGTH(package), -1); - if (dot == -2) { - goto error; - } - else if (dot == -1) { - goto no_parent_error; - } - PyObject *substr = PyUnicode_Substring(package, 0, dot); - if (substr == NULL) { - goto error; - } - Py_SETREF(package, substr); - } - } - - last_dot = PyUnicode_GET_LENGTH(package); - if (last_dot == 0) { - goto no_parent_error; - } - - for (level_up = 1; level_up < level; level_up += 1) { - last_dot = PyUnicode_FindChar(package, '.', 0, last_dot, -1); - if (last_dot == -2) { - goto error; - } - else if (last_dot == -1) { - _PyErr_SetString(tstate, PyExc_ImportError, - "attempted relative import beyond top-level " - "package"); - goto error; - } - } - - base = PyUnicode_Substring(package, 0, last_dot); - Py_DECREF(package); - if (base == NULL || PyUnicode_GET_LENGTH(name) == 0) { - return base; - } - - abs_name = PyUnicode_FromFormat("%U.%U", base, name); - Py_DECREF(base); - return abs_name; - - no_parent_error: - _PyErr_SetString(tstate, PyExc_ImportError, - "attempted relative import " - "with no known parent package"); - - error: - Py_XDECREF(package); - return NULL; -} - -static PyObject * -import_find_and_load(PyThreadState *tstate, PyObject *abs_name) -{ - _Py_IDENTIFIER(_find_and_load); - PyObject *mod = NULL; - PyInterpreterState *interp = tstate->interp; - int import_time = _PyInterpreterState_GetConfig(interp)->import_time; - static int import_level; - static _PyTime_t accumulated; - - _PyTime_t t1 = 0, accumulated_copy = accumulated; - - PyObject *sys_path = PySys_GetObject("path"); - PyObject *sys_meta_path = PySys_GetObject("meta_path"); - PyObject *sys_path_hooks = PySys_GetObject("path_hooks"); - if (_PySys_Audit(tstate, "import", "OOOOO", - abs_name, Py_None, sys_path ? sys_path : Py_None, - sys_meta_path ? sys_meta_path : Py_None, - sys_path_hooks ? sys_path_hooks : Py_None) < 0) { - return NULL; - } - - - /* XOptions is initialized after first some imports. - * So we can't have negative cache before completed initialization. - * Anyway, importlib._find_and_load is much slower than - * _PyDict_GetItemIdWithError(). - */ - if (import_time) { - static int header = 1; - if (header) { - fputs("import time: self [us] | cumulative | imported package\n", - stderr); - header = 0; - } - - import_level++; - t1 = _PyTime_GetPerfCounter(); - accumulated = 0; - } - - if (PyDTrace_IMPORT_FIND_LOAD_START_ENABLED()) - PyDTrace_IMPORT_FIND_LOAD_START(PyUnicode_AsUTF8(abs_name)); - - mod = _PyObject_CallMethodIdObjArgs(interp->importlib, - &PyId__find_and_load, abs_name, - interp->import_func, NULL); - - if (PyDTrace_IMPORT_FIND_LOAD_DONE_ENABLED()) - PyDTrace_IMPORT_FIND_LOAD_DONE(PyUnicode_AsUTF8(abs_name), - mod != NULL); - - if (import_time) { - _PyTime_t cum = _PyTime_GetPerfCounter() - t1; - - import_level--; - fprintf(stderr, "import time: %9ld | %10ld | %*s%s\n", - (long)_PyTime_AsMicroseconds(cum - accumulated, _PyTime_ROUND_CEILING), - (long)_PyTime_AsMicroseconds(cum, _PyTime_ROUND_CEILING), - import_level*2, "", PyUnicode_AsUTF8(abs_name)); - - accumulated = accumulated_copy + cum; - } - - return mod; -} - -PyObject * -PyImport_GetModule(PyObject *name) -{ - PyThreadState *tstate = _PyThreadState_GET(); - PyObject *mod; - - mod = import_get_module(tstate, name); - if (mod != NULL && mod != Py_None) { - if (import_ensure_initialized(tstate->interp, mod, name) < 0) { - Py_DECREF(mod); - remove_importlib_frames(tstate); - return NULL; - } - } - return mod; -} - -PyObject * -PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals, - PyObject *locals, PyObject *fromlist, - int level) -{ - PyThreadState *tstate = _PyThreadState_GET(); - _Py_IDENTIFIER(_handle_fromlist); - PyObject *abs_name = NULL; - PyObject *final_mod = NULL; - PyObject *mod = NULL; - PyObject *package = NULL; - PyInterpreterState *interp = tstate->interp; - int has_from; - - if (name == NULL) { - _PyErr_SetString(tstate, PyExc_ValueError, "Empty module name"); - goto error; - } - - /* The below code is importlib.__import__() & _gcd_import(), ported to C - for added performance. */ - - if (!PyUnicode_Check(name)) { - _PyErr_SetString(tstate, PyExc_TypeError, - "module name must be a string"); - goto error; - } - if (PyUnicode_READY(name) < 0) { - goto error; - } - if (level < 0) { - _PyErr_SetString(tstate, PyExc_ValueError, "level must be >= 0"); - goto error; - } - - if (level > 0) { - abs_name = resolve_name(tstate, name, globals, level); - if (abs_name == NULL) - goto error; - } - else { /* level == 0 */ - if (PyUnicode_GET_LENGTH(name) == 0) { - _PyErr_SetString(tstate, PyExc_ValueError, "Empty module name"); - goto error; - } - abs_name = name; - Py_INCREF(abs_name); - } - - mod = import_get_module(tstate, abs_name); - if (mod == NULL && _PyErr_Occurred(tstate)) { - goto error; - } - - if (mod != NULL && mod != Py_None) { - if (import_ensure_initialized(tstate->interp, mod, abs_name) < 0) { - goto error; - } - } - else { - Py_XDECREF(mod); - mod = import_find_and_load(tstate, abs_name); - if (mod == NULL) { - goto error; - } - } - - has_from = 0; - if (fromlist != NULL && fromlist != Py_None) { - has_from = PyObject_IsTrue(fromlist); - if (has_from < 0) - goto error; - } - if (!has_from) { - Py_ssize_t len = PyUnicode_GET_LENGTH(name); - if (level == 0 || len > 0) { - Py_ssize_t dot; - - dot = PyUnicode_FindChar(name, '.', 0, len, 1); - if (dot == -2) { - goto error; - } - - if (dot == -1) { - /* No dot in module name, simple exit */ - final_mod = mod; - Py_INCREF(mod); - goto error; - } - - if (level == 0) { - PyObject *front = PyUnicode_Substring(name, 0, dot); - if (front == NULL) { - goto error; - } - - final_mod = PyImport_ImportModuleLevelObject(front, NULL, NULL, NULL, 0); - Py_DECREF(front); - } - else { - Py_ssize_t cut_off = len - dot; - Py_ssize_t abs_name_len = PyUnicode_GET_LENGTH(abs_name); - PyObject *to_return = PyUnicode_Substring(abs_name, 0, - abs_name_len - cut_off); - if (to_return == NULL) { - goto error; - } - - final_mod = import_get_module(tstate, to_return); - Py_DECREF(to_return); - if (final_mod == NULL) { - if (!_PyErr_Occurred(tstate)) { - _PyErr_Format(tstate, PyExc_KeyError, - "%R not in sys.modules as expected", - to_return); - } - goto error; - } - } - } - else { - final_mod = mod; - Py_INCREF(mod); - } - } - else { - PyObject *path; - if (_PyObject_LookupAttrId(mod, &PyId___path__, &path) < 0) { - goto error; - } - if (path) { - Py_DECREF(path); - final_mod = _PyObject_CallMethodIdObjArgs( - interp->importlib, &PyId__handle_fromlist, - mod, fromlist, interp->import_func, NULL); - } - else { - final_mod = mod; - Py_INCREF(mod); - } - } - - error: - Py_XDECREF(abs_name); - Py_XDECREF(mod); - Py_XDECREF(package); - if (final_mod == NULL) { - remove_importlib_frames(tstate); - } - return final_mod; -} - -PyObject * -PyImport_ImportModuleLevel(const char *name, PyObject *globals, PyObject *locals, - PyObject *fromlist, int level) -{ - PyObject *nameobj, *mod; - nameobj = PyUnicode_FromString(name); - if (nameobj == NULL) - return NULL; - mod = PyImport_ImportModuleLevelObject(nameobj, globals, locals, - fromlist, level); - Py_DECREF(nameobj); - return mod; -} - - -/* Re-import a module of any kind and return its module object, WITH - INCREMENTED REFERENCE COUNT */ - -PyObject * -PyImport_ReloadModule(PyObject *m) -{ - _Py_IDENTIFIER(importlib); - _Py_IDENTIFIER(reload); - PyObject *reloaded_module = NULL; - PyObject *importlib = _PyImport_GetModuleId(&PyId_importlib); - if (importlib == NULL) { - if (PyErr_Occurred()) { - return NULL; - } - - importlib = PyImport_ImportModule("importlib"); - if (importlib == NULL) { - return NULL; - } - } - - reloaded_module = _PyObject_CallMethodIdOneArg(importlib, &PyId_reload, m); - Py_DECREF(importlib); - return reloaded_module; -} - - -/* Higher-level import emulator which emulates the "import" statement - more accurately -- it invokes the __import__() function from the - builtins of the current globals. This means that the import is - done using whatever import hooks are installed in the current - environment. - A dummy list ["__doc__"] is passed as the 4th argument so that - e.g. PyImport_Import(PyUnicode_FromString("win32com.client.gencache")) - will return <module "gencache"> instead of <module "win32com">. */ - -PyObject * -PyImport_Import(PyObject *module_name) -{ - _Py_IDENTIFIER(__import__); - _Py_IDENTIFIER(__builtins__); - - PyThreadState *tstate = _PyThreadState_GET(); - PyObject *globals = NULL; - PyObject *import = NULL; - PyObject *builtins = NULL; - PyObject *r = NULL; - - /* Initialize constant string objects */ - PyObject *import_str = _PyUnicode_FromId(&PyId___import__); // borrowed ref - if (import_str == NULL) { - return NULL; - } - - PyObject *builtins_str = _PyUnicode_FromId(&PyId___builtins__); // borrowed ref - if (builtins_str == NULL) { - return NULL; - } - - PyObject *from_list = PyList_New(0); - if (from_list == NULL) { - goto err; - } - - /* Get the builtins from current globals */ - globals = PyEval_GetGlobals(); - if (globals != NULL) { - Py_INCREF(globals); - builtins = PyObject_GetItem(globals, builtins_str); - if (builtins == NULL) - goto err; - } - else { - /* No globals -- use standard builtins, and fake globals */ - builtins = PyImport_ImportModuleLevel("builtins", - NULL, NULL, NULL, 0); - if (builtins == NULL) { - goto err; - } - globals = Py_BuildValue("{OO}", builtins_str, builtins); - if (globals == NULL) - goto err; - } - - /* Get the __import__ function from the builtins */ - if (PyDict_Check(builtins)) { - import = PyObject_GetItem(builtins, import_str); - if (import == NULL) { - _PyErr_SetObject(tstate, PyExc_KeyError, import_str); - } - } - else - import = PyObject_GetAttr(builtins, import_str); - if (import == NULL) - goto err; - - /* Call the __import__ function with the proper argument list - Always use absolute import here. - Calling for side-effect of import. */ - r = PyObject_CallFunction(import, "OOOOi", module_name, globals, - globals, from_list, 0, NULL); - if (r == NULL) - goto err; - Py_DECREF(r); - - r = import_get_module(tstate, module_name); - if (r == NULL && !_PyErr_Occurred(tstate)) { - _PyErr_SetObject(tstate, PyExc_KeyError, module_name); - } - - err: - Py_XDECREF(globals); - Py_XDECREF(builtins); - Py_XDECREF(import); - Py_XDECREF(from_list); - - return r; -} - -/*[clinic input] -_imp.extension_suffixes - -Returns the list of file suffixes used to identify extension modules. -[clinic start generated code]*/ - -static PyObject * -_imp_extension_suffixes_impl(PyObject *module) -/*[clinic end generated code: output=0bf346e25a8f0cd3 input=ecdeeecfcb6f839e]*/ -{ - PyObject *list; - - list = PyList_New(0); - if (list == NULL) - return NULL; -#ifdef HAVE_DYNAMIC_LOADING - const char *suffix; - unsigned int index = 0; - - while ((suffix = _PyImport_DynLoadFiletab[index])) { - PyObject *item = PyUnicode_FromString(suffix); - if (item == NULL) { - Py_DECREF(list); - return NULL; - } - if (PyList_Append(list, item) < 0) { - Py_DECREF(list); - Py_DECREF(item); - return NULL; - } - Py_DECREF(item); - index += 1; - } -#endif - return list; -} - -/*[clinic input] -_imp.init_frozen - - name: unicode - / - -Initializes a frozen module. -[clinic start generated code]*/ - -static PyObject * -_imp_init_frozen_impl(PyObject *module, PyObject *name) -/*[clinic end generated code: output=fc0511ed869fd69c input=13019adfc04f3fb3]*/ -{ - PyThreadState *tstate = _PyThreadState_GET(); - int ret; - - ret = PyImport_ImportFrozenModuleObject(name); - if (ret < 0) - return NULL; - if (ret == 0) { - Py_RETURN_NONE; - } - return import_add_module(tstate, name); -} - -/*[clinic input] -_imp.get_frozen_object - - name: unicode - / - -Create a code object for a frozen module. -[clinic start generated code]*/ - -static PyObject * -_imp_get_frozen_object_impl(PyObject *module, PyObject *name) -/*[clinic end generated code: output=2568cc5b7aa0da63 input=ed689bc05358fdbd]*/ -{ - return get_frozen_object(name); -} - -/*[clinic input] -_imp.is_frozen_package - - name: unicode - / - -Returns True if the module name is of a frozen package. -[clinic start generated code]*/ - -static PyObject * -_imp_is_frozen_package_impl(PyObject *module, PyObject *name) -/*[clinic end generated code: output=e70cbdb45784a1c9 input=81b6cdecd080fbb8]*/ -{ - return is_frozen_package(name); -} - -/*[clinic input] -_imp.is_builtin - - name: unicode - / - -Returns True if the module name corresponds to a built-in module. -[clinic start generated code]*/ - -static PyObject * -_imp_is_builtin_impl(PyObject *module, PyObject *name) -/*[clinic end generated code: output=3bfd1162e2d3be82 input=86befdac021dd1c7]*/ -{ - return PyLong_FromLong(is_builtin(name)); -} - -/*[clinic input] -_imp.is_frozen - - name: unicode - / - -Returns True if the module name corresponds to a frozen module. -[clinic start generated code]*/ - -static PyObject * -_imp_is_frozen_impl(PyObject *module, PyObject *name) -/*[clinic end generated code: output=01f408f5ec0f2577 input=7301dbca1897d66b]*/ -{ - const struct _frozen *p; - - p = find_frozen(name); - return PyBool_FromLong((long) (p == NULL ? 0 : p->size)); -} - -/* Common implementation for _imp.exec_dynamic and _imp.exec_builtin */ -static int -exec_builtin_or_dynamic(PyObject *mod) { - PyModuleDef *def; - void *state; - - if (!PyModule_Check(mod)) { - return 0; - } - - def = PyModule_GetDef(mod); - if (def == NULL) { - return 0; - } - - state = PyModule_GetState(mod); - if (state) { - /* Already initialized; skip reload */ - return 0; - } - - return PyModule_ExecDef(mod, def); -} - -#ifdef HAVE_DYNAMIC_LOADING - -/*[clinic input] -_imp.create_dynamic - - spec: object - file: object = NULL - / - -Create an extension module. -[clinic start generated code]*/ - -static PyObject * -_imp_create_dynamic_impl(PyObject *module, PyObject *spec, PyObject *file) -/*[clinic end generated code: output=83249b827a4fde77 input=c31b954f4cf4e09d]*/ -{ - PyObject *mod, *name, *path; - FILE *fp; - - name = PyObject_GetAttrString(spec, "name"); - if (name == NULL) { - return NULL; - } - - path = PyObject_GetAttrString(spec, "origin"); - if (path == NULL) { - Py_DECREF(name); - return NULL; - } - - PyThreadState *tstate = _PyThreadState_GET(); - mod = import_find_extension(tstate, name, path); - if (mod != NULL || PyErr_Occurred()) { - Py_DECREF(name); - Py_DECREF(path); - return mod; - } - - if (file != NULL) { - fp = _Py_fopen_obj(path, "r"); - if (fp == NULL) { - Py_DECREF(name); - Py_DECREF(path); - return NULL; - } - } - else - fp = NULL; - - mod = _PyImport_LoadDynamicModuleWithSpec(spec, fp); - - Py_DECREF(name); - Py_DECREF(path); - if (fp) - fclose(fp); - return mod; -} - -/*[clinic input] -_imp.exec_dynamic -> int - - mod: object - / - -Initialize an extension module. -[clinic start generated code]*/ - -static int -_imp_exec_dynamic_impl(PyObject *module, PyObject *mod) -/*[clinic end generated code: output=f5720ac7b465877d input=9fdbfcb250280d3a]*/ -{ - return exec_builtin_or_dynamic(mod); -} - - -#endif /* HAVE_DYNAMIC_LOADING */ - -/*[clinic input] -_imp.exec_builtin -> int - - mod: object - / - -Initialize a built-in module. -[clinic start generated code]*/ - -static int -_imp_exec_builtin_impl(PyObject *module, PyObject *mod) -/*[clinic end generated code: output=0262447b240c038e input=7beed5a2f12a60ca]*/ -{ - return exec_builtin_or_dynamic(mod); -} - -/*[clinic input] -_imp.source_hash - - key: long - source: Py_buffer -[clinic start generated code]*/ - -static PyObject * -_imp_source_hash_impl(PyObject *module, long key, Py_buffer *source) -/*[clinic end generated code: output=edb292448cf399ea input=9aaad1e590089789]*/ -{ - union { - uint64_t x; - char data[sizeof(uint64_t)]; - } hash; - hash.x = _Py_KeyedHash((uint64_t)key, source->buf, source->len); -#if !PY_LITTLE_ENDIAN - // Force to little-endian. There really ought to be a succinct standard way - // to do this. - for (size_t i = 0; i < sizeof(hash.data)/2; i++) { - char tmp = hash.data[i]; - hash.data[i] = hash.data[sizeof(hash.data) - i - 1]; - hash.data[sizeof(hash.data) - i - 1] = tmp; - } -#endif - return PyBytes_FromStringAndSize(hash.data, sizeof(hash.data)); -} - - -PyDoc_STRVAR(doc_imp, -"(Extremely) low-level import machinery bits as used by importlib and imp."); - -static PyMethodDef imp_methods[] = { - _IMP_EXTENSION_SUFFIXES_METHODDEF - _IMP_LOCK_HELD_METHODDEF - _IMP_ACQUIRE_LOCK_METHODDEF - _IMP_RELEASE_LOCK_METHODDEF - _IMP_GET_FROZEN_OBJECT_METHODDEF - _IMP_IS_FROZEN_PACKAGE_METHODDEF - _IMP_CREATE_BUILTIN_METHODDEF - _IMP_INIT_FROZEN_METHODDEF - _IMP_IS_BUILTIN_METHODDEF - _IMP_IS_FROZEN_METHODDEF - _IMP_CREATE_DYNAMIC_METHODDEF - _IMP_EXEC_DYNAMIC_METHODDEF - _IMP_EXEC_BUILTIN_METHODDEF - _IMP__FIX_CO_FILENAME_METHODDEF - _IMP_SOURCE_HASH_METHODDEF - {NULL, NULL} /* sentinel */ -}; - - -static int -imp_module_exec(PyObject *module) -{ - const wchar_t *mode = _Py_GetConfig()->check_hash_pycs_mode; - PyObject *pyc_mode = PyUnicode_FromWideChar(mode, -1); - if (pyc_mode == NULL) { - return -1; - } - if (PyModule_AddObjectRef(module, "check_hash_based_pycs", pyc_mode) < 0) { - Py_DECREF(pyc_mode); - return -1; - } - Py_DECREF(pyc_mode); - - return 0; -} - - -static PyModuleDef_Slot imp_slots[] = { - {Py_mod_exec, imp_module_exec}, - {0, NULL} -}; - -static struct PyModuleDef imp_module = { - PyModuleDef_HEAD_INIT, - .m_name = "_imp", - .m_doc = doc_imp, - .m_size = 0, - .m_methods = imp_methods, - .m_slots = imp_slots, -}; - -PyMODINIT_FUNC -PyInit__imp(void) -{ - return PyModuleDef_Init(&imp_module); -} - - -// Import the _imp extension by calling manually _imp.create_builtin() and -// _imp.exec_builtin() since importlib is not initialized yet. Initializing -// importlib requires the _imp module: this function fix the bootstrap issue. -PyObject* -_PyImport_BootstrapImp(PyThreadState *tstate) -{ - PyObject *name = PyUnicode_FromString("_imp"); - if (name == NULL) { - return NULL; - } - - // Mock a ModuleSpec object just good enough for PyModule_FromDefAndSpec(): - // an object with just a name attribute. - // - // _imp.__spec__ is overridden by importlib._bootstrap._instal() anyway. - PyObject *attrs = Py_BuildValue("{sO}", "name", name); - if (attrs == NULL) { - goto error; - } - PyObject *spec = _PyNamespace_New(attrs); - Py_DECREF(attrs); - if (spec == NULL) { - goto error; - } - - // Create the _imp module from its definition. - PyObject *mod = create_builtin(tstate, name, spec); - Py_CLEAR(name); - Py_DECREF(spec); - if (mod == NULL) { - goto error; - } - assert(mod != Py_None); // not found - - // Execute the _imp module: call imp_module_exec(). - if (exec_builtin_or_dynamic(mod) < 0) { - Py_DECREF(mod); - goto error; - } - return mod; - -error: - Py_XDECREF(name); - return NULL; -} - - -/* API for embedding applications that want to add their own entries - to the table of built-in modules. This should normally be called - *before* Py_Initialize(). When the table resize fails, -1 is - returned and the existing table is unchanged. - - After a similar function by Just van Rossum. */ - -int -PyImport_ExtendInittab(struct _inittab *newtab) -{ - struct _inittab *p; - size_t i, n; - int res = 0; - - /* Count the number of entries in both tables */ - for (n = 0; newtab[n].name != NULL; n++) - ; - if (n == 0) - return 0; /* Nothing to do */ - for (i = 0; PyImport_Inittab[i].name != NULL; i++) - ; - - /* Force default raw memory allocator to get a known allocator to be able - to release the memory in _PyImport_Fini2() */ - PyMemAllocatorEx old_alloc; - _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - - /* Allocate new memory for the combined table */ - p = NULL; - if (i + n <= SIZE_MAX / sizeof(struct _inittab) - 1) { - size_t size = sizeof(struct _inittab) * (i + n + 1); - p = PyMem_RawRealloc(inittab_copy, size); - } - if (p == NULL) { - res = -1; - goto done; - } - - /* Copy the tables into the new memory at the first call - to PyImport_ExtendInittab(). */ - if (inittab_copy != PyImport_Inittab) { - memcpy(p, PyImport_Inittab, (i+1) * sizeof(struct _inittab)); - } - memcpy(p + i, newtab, (n + 1) * sizeof(struct _inittab)); - PyImport_Inittab = inittab_copy = p; - -done: - PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - return res; -} - -/* Shorthand to add a single entry given a name and a function */ - -int -PyImport_AppendInittab(const char *name, PyObject* (*initfunc)(void)) -{ - struct _inittab newtab[2]; - - memset(newtab, '\0', sizeof newtab); - - newtab[0].name = name; - newtab[0].initfunc = initfunc; - - return PyImport_ExtendInittab(newtab); -} - -#ifdef __cplusplus -} -#endif diff --git a/contrib/tools/python3/src/Python/importdl.c b/contrib/tools/python3/src/Python/importdl.c deleted file mode 100644 index 6d2554741f9..00000000000 --- a/contrib/tools/python3/src/Python/importdl.c +++ /dev/null @@ -1,248 +0,0 @@ - -/* Support for dynamic loading of extension modules */ - -#include "Python.h" - -/* ./configure sets HAVE_DYNAMIC_LOADING if dynamic loading of modules is - supported on this platform. configure will then compile and link in one - of the dynload_*.c files, as appropriate. We will call a function in - those modules to get a function pointer to the module's init function. -*/ -#ifdef HAVE_DYNAMIC_LOADING - -#include "importdl.h" - -#ifdef MS_WINDOWS -extern dl_funcptr _PyImport_FindSharedFuncptrWindows(const char *prefix, - const char *shortname, - PyObject *pathname, - FILE *fp); -#else -extern dl_funcptr _PyImport_FindSharedFuncptr(const char *prefix, - const char *shortname, - const char *pathname, FILE *fp); -#endif - -static const char * const ascii_only_prefix = "PyInit"; -static const char * const nonascii_prefix = "PyInitU"; - -/* Get the variable part of a module's export symbol name. - * Returns a bytes instance. For non-ASCII-named modules, the name is - * encoded as per PEP 489. - * The hook_prefix pointer is set to either ascii_only_prefix or - * nonascii_prefix, as appropriate. - */ -static PyObject * -get_encoded_name(PyObject *name, const char **hook_prefix) { - PyObject *tmp; - PyObject *encoded = NULL; - PyObject *modname = NULL; - Py_ssize_t name_len, lastdot; - _Py_IDENTIFIER(replace); - - /* Get the short name (substring after last dot) */ - name_len = PyUnicode_GetLength(name); - if (name_len < 0) { - return NULL; - } - lastdot = PyUnicode_FindChar(name, '.', 0, name_len, -1); - if (lastdot < -1) { - return NULL; - } else if (lastdot >= 0) { - tmp = PyUnicode_Substring(name, lastdot + 1, name_len); - if (tmp == NULL) - return NULL; - name = tmp; - /* "name" now holds a new reference to the substring */ - } else { - Py_INCREF(name); - } - - /* Encode to ASCII or Punycode, as needed */ - encoded = PyUnicode_AsEncodedString(name, "ascii", NULL); - if (encoded != NULL) { - *hook_prefix = ascii_only_prefix; - } else { - if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) { - PyErr_Clear(); - encoded = PyUnicode_AsEncodedString(name, "punycode", NULL); - if (encoded == NULL) { - goto error; - } - *hook_prefix = nonascii_prefix; - } else { - goto error; - } - } - - /* Replace '-' by '_' */ - modname = _PyObject_CallMethodId(encoded, &PyId_replace, "cc", '-', '_'); - if (modname == NULL) - goto error; - - Py_DECREF(name); - Py_DECREF(encoded); - return modname; -error: - Py_DECREF(name); - Py_XDECREF(encoded); - return NULL; -} - -PyObject * -_PyImport_LoadDynamicModuleWithSpec(PyObject *spec, FILE *fp) -{ -#ifndef MS_WINDOWS - PyObject *pathbytes = NULL; -#endif - PyObject *name_unicode = NULL, *name = NULL, *path = NULL, *m = NULL; - const char *name_buf, *hook_prefix; - const char *oldcontext; - dl_funcptr exportfunc; - PyModuleDef *def; - PyObject *(*p0)(void); - - name_unicode = PyObject_GetAttrString(spec, "name"); - if (name_unicode == NULL) { - return NULL; - } - if (!PyUnicode_Check(name_unicode)) { - PyErr_SetString(PyExc_TypeError, - "spec.name must be a string"); - goto error; - } - - name = get_encoded_name(name_unicode, &hook_prefix); - if (name == NULL) { - goto error; - } - name_buf = PyBytes_AS_STRING(name); - - path = PyObject_GetAttrString(spec, "origin"); - if (path == NULL) - goto error; - - if (PySys_Audit("import", "OOOOO", name_unicode, path, - Py_None, Py_None, Py_None) < 0) { - goto error; - } - -#ifdef MS_WINDOWS - exportfunc = _PyImport_FindSharedFuncptrWindows(hook_prefix, name_buf, - path, fp); -#else - pathbytes = PyUnicode_EncodeFSDefault(path); - if (pathbytes == NULL) - goto error; - exportfunc = _PyImport_FindSharedFuncptr(hook_prefix, name_buf, - PyBytes_AS_STRING(pathbytes), - fp); - Py_DECREF(pathbytes); -#endif - - if (exportfunc == NULL) { - if (!PyErr_Occurred()) { - PyObject *msg; - msg = PyUnicode_FromFormat( - "dynamic module does not define " - "module export function (%s_%s)", - hook_prefix, name_buf); - if (msg == NULL) - goto error; - PyErr_SetImportError(msg, name_unicode, path); - Py_DECREF(msg); - } - goto error; - } - - p0 = (PyObject *(*)(void))exportfunc; - - /* Package context is needed for single-phase init */ - oldcontext = _Py_PackageContext; - _Py_PackageContext = PyUnicode_AsUTF8(name_unicode); - if (_Py_PackageContext == NULL) { - _Py_PackageContext = oldcontext; - goto error; - } - m = p0(); - _Py_PackageContext = oldcontext; - - if (m == NULL) { - if (!PyErr_Occurred()) { - PyErr_Format( - PyExc_SystemError, - "initialization of %s failed without raising an exception", - name_buf); - } - goto error; - } else if (PyErr_Occurred()) { - PyErr_Clear(); - PyErr_Format( - PyExc_SystemError, - "initialization of %s raised unreported exception", - name_buf); - m = NULL; - goto error; - } - if (Py_IS_TYPE(m, NULL)) { - /* This can happen when a PyModuleDef is returned without calling - * PyModuleDef_Init on it - */ - PyErr_Format(PyExc_SystemError, - "init function of %s returned uninitialized object", - name_buf); - m = NULL; /* prevent segfault in DECREF */ - goto error; - } - if (PyObject_TypeCheck(m, &PyModuleDef_Type)) { - Py_DECREF(name_unicode); - Py_DECREF(name); - Py_DECREF(path); - return PyModule_FromDefAndSpec((PyModuleDef*)m, spec); - } - - /* Fall back to single-phase init mechanism */ - - if (hook_prefix == nonascii_prefix) { - /* don't allow legacy init for non-ASCII module names */ - PyErr_Format( - PyExc_SystemError, - "initialization of %s did not return PyModuleDef", - name_buf); - goto error; - } - - /* Remember pointer to module init function. */ - def = PyModule_GetDef(m); - if (def == NULL) { - PyErr_Format(PyExc_SystemError, - "initialization of %s did not return an extension " - "module", name_buf); - goto error; - } - def->m_base.m_init = p0; - - /* Remember the filename as the __file__ attribute */ - if (PyModule_AddObjectRef(m, "__file__", path) < 0) { - PyErr_Clear(); /* Not important enough to report */ - } - - PyObject *modules = PyImport_GetModuleDict(); - if (_PyImport_FixupExtensionObject(m, name_unicode, path, modules) < 0) - goto error; - - Py_DECREF(name_unicode); - Py_DECREF(name); - Py_DECREF(path); - - return m; - -error: - Py_DECREF(name_unicode); - Py_XDECREF(name); - Py_XDECREF(path); - Py_XDECREF(m); - return NULL; -} - -#endif /* HAVE_DYNAMIC_LOADING */ diff --git a/contrib/tools/python3/src/Python/importdl.h b/contrib/tools/python3/src/Python/importdl.h deleted file mode 100644 index 9847652b1f1..00000000000 --- a/contrib/tools/python3/src/Python/importdl.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef Py_IMPORTDL_H -#define Py_IMPORTDL_H - -#ifdef __cplusplus -extern "C" { -#endif - - -extern const char *_PyImport_DynLoadFiletab[]; - -extern PyObject *_PyImport_LoadDynamicModuleWithSpec(PyObject *spec, FILE *); - -/* Max length of module suffix searched for -- accommodates "module.slb" */ -#define MAXSUFFIXSIZE 12 - -#ifdef MS_WINDOWS -#include <windows.h> -typedef FARPROC dl_funcptr; -#else -typedef void (*dl_funcptr)(void); -#endif - - -#ifdef __cplusplus -} -#endif -#endif /* !Py_IMPORTDL_H */ diff --git a/contrib/tools/python3/src/Python/importlib.h b/contrib/tools/python3/src/Python/importlib.h deleted file mode 100644 index dd1a9f172c0..00000000000 --- a/contrib/tools/python3/src/Python/importlib.h +++ /dev/null @@ -1,1885 +0,0 @@ -/* Auto-generated by Programs/_freeze_importlib.c */ -const unsigned char _Py_M__importlib_bootstrap[] = { - 99,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,4,0,0,0,64,0,0,0,115,214,1,0,0,100,0, - 90,0,100,1,100,2,132,0,90,1,100,3,90,2,100,3, - 90,3,100,3,90,4,100,3,97,5,100,4,100,5,132,0, - 90,6,100,6,100,7,132,0,90,7,105,0,90,8,105,0, - 90,9,71,0,100,8,100,9,132,0,100,9,101,10,131,3, - 90,11,71,0,100,10,100,11,132,0,100,11,131,2,90,12, - 71,0,100,12,100,13,132,0,100,13,131,2,90,13,71,0, - 100,14,100,15,132,0,100,15,131,2,90,14,100,16,100,17, - 132,0,90,15,100,18,100,19,132,0,90,16,100,20,100,21, - 132,0,90,17,100,22,100,23,156,1,100,24,100,25,132,2, - 90,18,100,26,100,27,132,0,90,19,100,28,100,29,132,0, - 90,20,100,30,100,31,132,0,90,21,100,32,100,33,132,0, - 90,22,71,0,100,34,100,35,132,0,100,35,131,2,90,23, - 100,3,100,3,100,36,156,2,100,37,100,38,132,2,90,24, - 100,96,100,39,100,40,132,1,90,25,100,41,100,42,156,1, - 100,43,100,44,132,2,90,26,100,45,100,46,132,0,90,27, - 100,47,100,48,132,0,90,28,100,49,100,50,132,0,90,29, - 100,51,100,52,132,0,90,30,100,53,100,54,132,0,90,31, - 100,55,100,56,132,0,90,32,71,0,100,57,100,58,132,0, - 100,58,131,2,90,33,71,0,100,59,100,60,132,0,100,60, - 131,2,90,34,71,0,100,61,100,62,132,0,100,62,131,2, - 90,35,100,63,100,64,132,0,90,36,100,65,100,66,132,0, - 90,37,100,97,100,67,100,68,132,1,90,38,100,69,100,70, - 132,0,90,39,100,71,90,40,101,40,100,72,23,0,90,41, - 100,73,100,74,132,0,90,42,101,43,131,0,90,44,100,75, - 100,76,132,0,90,45,100,98,100,78,100,79,132,1,90,46, - 100,41,100,80,156,1,100,81,100,82,132,2,90,47,100,83, - 100,84,132,0,90,48,100,99,100,86,100,87,132,1,90,49, - 100,88,100,89,132,0,90,50,100,90,100,91,132,0,90,51, - 100,92,100,93,132,0,90,52,100,94,100,95,132,0,90,53, - 100,3,83,0,41,100,97,83,1,0,0,67,111,114,101,32, - 105,109,112,108,101,109,101,110,116,97,116,105,111,110,32,111, - 102,32,105,109,112,111,114,116,46,10,10,84,104,105,115,32, - 109,111,100,117,108,101,32,105,115,32,78,79,84,32,109,101, - 97,110,116,32,116,111,32,98,101,32,100,105,114,101,99,116, - 108,121,32,105,109,112,111,114,116,101,100,33,32,73,116,32, - 104,97,115,32,98,101,101,110,32,100,101,115,105,103,110,101, - 100,32,115,117,99,104,10,116,104,97,116,32,105,116,32,99, - 97,110,32,98,101,32,98,111,111,116,115,116,114,97,112,112, - 101,100,32,105,110,116,111,32,80,121,116,104,111,110,32,97, - 115,32,116,104,101,32,105,109,112,108,101,109,101,110,116,97, - 116,105,111,110,32,111,102,32,105,109,112,111,114,116,46,32, - 65,115,10,115,117,99,104,32,105,116,32,114,101,113,117,105, - 114,101,115,32,116,104,101,32,105,110,106,101,99,116,105,111, - 110,32,111,102,32,115,112,101,99,105,102,105,99,32,109,111, - 100,117,108,101,115,32,97,110,100,32,97,116,116,114,105,98, - 117,116,101,115,32,105,110,32,111,114,100,101,114,32,116,111, - 10,119,111,114,107,46,32,79,110,101,32,115,104,111,117,108, - 100,32,117,115,101,32,105,109,112,111,114,116,108,105,98,32, - 97,115,32,116,104,101,32,112,117,98,108,105,99,45,102,97, - 99,105,110,103,32,118,101,114,115,105,111,110,32,111,102,32, - 116,104,105,115,32,109,111,100,117,108,101,46,10,10,99,1, - 0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,8, - 0,0,0,67,0,0,0,115,38,0,0,0,122,4,124,0, - 106,0,87,0,83,0,4,0,116,1,121,18,1,0,1,0, - 1,0,116,2,124,0,131,1,106,0,6,0,89,0,83,0, - 119,0,169,1,78,41,3,218,12,95,95,113,117,97,108,110, - 97,109,101,95,95,218,14,65,116,116,114,105,98,117,116,101, - 69,114,114,111,114,218,4,116,121,112,101,41,1,218,3,111, - 98,106,169,0,114,5,0,0,0,250,29,60,102,114,111,122, - 101,110,32,105,109,112,111,114,116,108,105,98,46,95,98,111, - 111,116,115,116,114,97,112,62,218,12,95,111,98,106,101,99, - 116,95,110,97,109,101,23,0,0,0,115,10,0,0,0,2, - 1,8,1,12,1,14,1,2,255,114,7,0,0,0,78,99, - 2,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0, - 7,0,0,0,67,0,0,0,115,56,0,0,0,100,1,68, - 0,93,16,125,2,116,0,124,1,124,2,131,2,114,18,116, - 1,124,0,124,2,116,2,124,1,124,2,131,2,131,3,1, - 0,113,2,124,0,106,3,160,4,124,1,106,3,161,1,1, - 0,100,2,83,0,41,3,122,47,83,105,109,112,108,101,32, - 115,117,98,115,116,105,116,117,116,101,32,102,111,114,32,102, - 117,110,99,116,111,111,108,115,46,117,112,100,97,116,101,95, - 119,114,97,112,112,101,114,46,41,4,218,10,95,95,109,111, - 100,117,108,101,95,95,218,8,95,95,110,97,109,101,95,95, - 114,1,0,0,0,218,7,95,95,100,111,99,95,95,78,41, - 5,218,7,104,97,115,97,116,116,114,218,7,115,101,116,97, - 116,116,114,218,7,103,101,116,97,116,116,114,218,8,95,95, - 100,105,99,116,95,95,218,6,117,112,100,97,116,101,41,3, - 90,3,110,101,119,90,3,111,108,100,218,7,114,101,112,108, - 97,99,101,114,5,0,0,0,114,5,0,0,0,114,6,0, - 0,0,218,5,95,119,114,97,112,40,0,0,0,115,10,0, - 0,0,8,2,10,1,18,1,2,128,18,1,114,17,0,0, - 0,99,1,0,0,0,0,0,0,0,0,0,0,0,1,0, - 0,0,2,0,0,0,67,0,0,0,115,12,0,0,0,116, - 0,116,1,131,1,124,0,131,1,83,0,114,0,0,0,0, - 41,2,114,3,0,0,0,218,3,115,121,115,169,1,218,4, - 110,97,109,101,114,5,0,0,0,114,5,0,0,0,114,6, - 0,0,0,218,11,95,110,101,119,95,109,111,100,117,108,101, - 48,0,0,0,115,2,0,0,0,12,1,114,21,0,0,0, - 99,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,1,0,0,0,64,0,0,0,115,12,0,0,0,101,0, - 90,1,100,0,90,2,100,1,83,0,41,2,218,14,95,68, - 101,97,100,108,111,99,107,69,114,114,111,114,78,41,3,114, - 9,0,0,0,114,8,0,0,0,114,1,0,0,0,114,5, - 0,0,0,114,5,0,0,0,114,5,0,0,0,114,6,0, - 0,0,114,22,0,0,0,61,0,0,0,115,4,0,0,0, - 8,0,4,1,114,22,0,0,0,99,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,2,0,0,0,64,0, - 0,0,115,56,0,0,0,101,0,90,1,100,0,90,2,100, - 1,90,3,100,2,100,3,132,0,90,4,100,4,100,5,132, - 0,90,5,100,6,100,7,132,0,90,6,100,8,100,9,132, - 0,90,7,100,10,100,11,132,0,90,8,100,12,83,0,41, - 13,218,11,95,77,111,100,117,108,101,76,111,99,107,122,169, - 65,32,114,101,99,117,114,115,105,118,101,32,108,111,99,107, - 32,105,109,112,108,101,109,101,110,116,97,116,105,111,110,32, - 119,104,105,99,104,32,105,115,32,97,98,108,101,32,116,111, - 32,100,101,116,101,99,116,32,100,101,97,100,108,111,99,107, - 115,10,32,32,32,32,40,101,46,103,46,32,116,104,114,101, - 97,100,32,49,32,116,114,121,105,110,103,32,116,111,32,116, - 97,107,101,32,108,111,99,107,115,32,65,32,116,104,101,110, - 32,66,44,32,97,110,100,32,116,104,114,101,97,100,32,50, - 32,116,114,121,105,110,103,32,116,111,10,32,32,32,32,116, - 97,107,101,32,108,111,99,107,115,32,66,32,116,104,101,110, - 32,65,41,46,10,32,32,32,32,99,2,0,0,0,0,0, - 0,0,0,0,0,0,2,0,0,0,2,0,0,0,67,0, - 0,0,115,48,0,0,0,116,0,160,1,161,0,124,0,95, - 2,116,0,160,1,161,0,124,0,95,3,124,1,124,0,95, - 4,100,0,124,0,95,5,100,1,124,0,95,6,100,1,124, - 0,95,7,100,0,83,0,169,2,78,233,0,0,0,0,41, - 8,218,7,95,116,104,114,101,97,100,90,13,97,108,108,111, - 99,97,116,101,95,108,111,99,107,218,4,108,111,99,107,218, - 6,119,97,107,101,117,112,114,20,0,0,0,218,5,111,119, - 110,101,114,218,5,99,111,117,110,116,218,7,119,97,105,116, - 101,114,115,169,2,218,4,115,101,108,102,114,20,0,0,0, - 114,5,0,0,0,114,5,0,0,0,114,6,0,0,0,218, - 8,95,95,105,110,105,116,95,95,71,0,0,0,115,12,0, - 0,0,10,1,10,1,6,1,6,1,6,1,10,1,122,20, - 95,77,111,100,117,108,101,76,111,99,107,46,95,95,105,110, - 105,116,95,95,99,1,0,0,0,0,0,0,0,0,0,0, - 0,5,0,0,0,3,0,0,0,67,0,0,0,115,86,0, - 0,0,116,0,160,1,161,0,125,1,124,0,106,2,125,2, - 116,3,131,0,125,3,9,0,116,4,160,5,124,2,161,1, - 125,4,124,4,100,0,117,0,114,22,100,2,83,0,124,4, - 106,2,125,2,124,2,124,1,107,2,114,31,100,1,83,0, - 124,2,124,3,118,0,114,37,100,2,83,0,124,3,160,6, - 124,2,161,1,1,0,113,11,41,3,78,84,70,41,7,114, - 26,0,0,0,218,9,103,101,116,95,105,100,101,110,116,114, - 29,0,0,0,218,3,115,101,116,218,12,95,98,108,111,99, - 107,105,110,103,95,111,110,218,3,103,101,116,218,3,97,100, - 100,41,5,114,33,0,0,0,90,2,109,101,218,3,116,105, - 100,90,4,115,101,101,110,114,27,0,0,0,114,5,0,0, - 0,114,5,0,0,0,114,6,0,0,0,218,12,104,97,115, - 95,100,101,97,100,108,111,99,107,79,0,0,0,115,28,0, - 0,0,8,2,6,1,6,1,2,1,10,1,8,1,4,1, - 6,1,8,1,4,1,8,1,4,6,10,1,2,242,122,24, - 95,77,111,100,117,108,101,76,111,99,107,46,104,97,115,95, - 100,101,97,100,108,111,99,107,99,1,0,0,0,0,0,0, - 0,0,0,0,0,2,0,0,0,8,0,0,0,67,0,0, - 0,115,200,0,0,0,116,0,160,1,161,0,125,1,124,0, - 116,2,124,1,60,0,122,87,9,0,124,0,106,3,143,64, - 1,0,124,0,106,4,100,2,107,2,115,24,124,0,106,5, - 124,1,107,2,114,47,124,1,124,0,95,5,124,0,4,0, - 106,4,100,3,55,0,2,0,95,4,9,0,87,0,100,4, - 4,0,4,0,131,3,1,0,87,0,116,2,124,1,61,0, - 100,1,83,0,124,0,160,6,161,0,114,57,116,7,100,5, - 124,0,22,0,131,1,130,1,124,0,106,8,160,9,100,6, - 161,1,114,70,124,0,4,0,106,10,100,3,55,0,2,0, - 95,10,87,0,100,4,4,0,4,0,131,3,1,0,110,8, - 49,0,115,80,119,1,1,0,1,0,1,0,89,0,1,0, - 124,0,106,8,160,9,161,0,1,0,124,0,106,8,160,11, - 161,0,1,0,113,10,116,2,124,1,61,0,119,0,41,7, - 122,185,10,32,32,32,32,32,32,32,32,65,99,113,117,105, - 114,101,32,116,104,101,32,109,111,100,117,108,101,32,108,111, - 99,107,46,32,32,73,102,32,97,32,112,111,116,101,110,116, - 105,97,108,32,100,101,97,100,108,111,99,107,32,105,115,32, - 100,101,116,101,99,116,101,100,44,10,32,32,32,32,32,32, - 32,32,97,32,95,68,101,97,100,108,111,99,107,69,114,114, - 111,114,32,105,115,32,114,97,105,115,101,100,46,10,32,32, - 32,32,32,32,32,32,79,116,104,101,114,119,105,115,101,44, - 32,116,104,101,32,108,111,99,107,32,105,115,32,97,108,119, - 97,121,115,32,97,99,113,117,105,114,101,100,32,97,110,100, - 32,84,114,117,101,32,105,115,32,114,101,116,117,114,110,101, - 100,46,10,32,32,32,32,32,32,32,32,84,114,25,0,0, - 0,233,1,0,0,0,78,122,23,100,101,97,100,108,111,99, - 107,32,100,101,116,101,99,116,101,100,32,98,121,32,37,114, - 70,41,12,114,26,0,0,0,114,35,0,0,0,114,37,0, - 0,0,114,27,0,0,0,114,30,0,0,0,114,29,0,0, - 0,114,41,0,0,0,114,22,0,0,0,114,28,0,0,0, - 218,7,97,99,113,117,105,114,101,114,31,0,0,0,218,7, - 114,101,108,101,97,115,101,169,2,114,33,0,0,0,114,40, - 0,0,0,114,5,0,0,0,114,5,0,0,0,114,6,0, - 0,0,114,43,0,0,0,100,0,0,0,115,42,0,0,0, - 8,6,8,1,2,1,2,1,8,1,20,1,6,1,14,1, - 2,1,14,252,10,13,8,248,12,1,12,1,14,1,2,128, - 28,248,10,10,10,1,2,244,8,14,122,19,95,77,111,100, - 117,108,101,76,111,99,107,46,97,99,113,117,105,114,101,99, - 1,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0, - 8,0,0,0,67,0,0,0,115,176,0,0,0,116,0,160, - 1,161,0,125,1,124,0,106,2,143,71,1,0,124,0,106, - 3,124,1,107,3,114,17,116,4,100,1,131,1,130,1,124, - 0,106,5,100,2,107,4,115,24,74,0,130,1,124,0,4, - 0,106,5,100,3,56,0,2,0,95,5,124,0,106,5,100, - 2,107,2,114,62,100,0,124,0,95,3,124,0,106,6,114, - 70,124,0,4,0,106,6,100,3,56,0,2,0,95,6,124, - 0,106,7,160,8,161,0,1,0,87,0,100,0,4,0,4, - 0,131,3,1,0,100,0,83,0,87,0,100,0,4,0,4, - 0,131,3,1,0,100,0,83,0,87,0,100,0,4,0,4, - 0,131,3,1,0,100,0,83,0,49,0,115,81,119,1,1, - 0,1,0,1,0,89,0,1,0,100,0,83,0,41,4,78, - 250,31,99,97,110,110,111,116,32,114,101,108,101,97,115,101, - 32,117,110,45,97,99,113,117,105,114,101,100,32,108,111,99, - 107,114,25,0,0,0,114,42,0,0,0,41,9,114,26,0, - 0,0,114,35,0,0,0,114,27,0,0,0,114,29,0,0, - 0,218,12,82,117,110,116,105,109,101,69,114,114,111,114,114, - 30,0,0,0,114,31,0,0,0,114,28,0,0,0,114,44, - 0,0,0,114,45,0,0,0,114,5,0,0,0,114,5,0, - 0,0,114,6,0,0,0,114,44,0,0,0,125,0,0,0, - 115,32,0,0,0,8,1,8,1,10,1,8,1,14,1,14, - 1,10,1,6,1,6,1,14,1,12,1,14,247,2,5,14, - 251,2,7,34,249,122,19,95,77,111,100,117,108,101,76,111, - 99,107,46,114,101,108,101,97,115,101,99,1,0,0,0,0, - 0,0,0,0,0,0,0,1,0,0,0,5,0,0,0,67, - 0,0,0,243,18,0,0,0,100,1,160,0,124,0,106,1, - 116,2,124,0,131,1,161,2,83,0,41,2,78,122,23,95, - 77,111,100,117,108,101,76,111,99,107,40,123,33,114,125,41, - 32,97,116,32,123,125,169,3,218,6,102,111,114,109,97,116, - 114,20,0,0,0,218,2,105,100,169,1,114,33,0,0,0, - 114,5,0,0,0,114,5,0,0,0,114,6,0,0,0,218, - 8,95,95,114,101,112,114,95,95,138,0,0,0,243,2,0, - 0,0,18,1,122,20,95,77,111,100,117,108,101,76,111,99, - 107,46,95,95,114,101,112,114,95,95,78,41,9,114,9,0, - 0,0,114,8,0,0,0,114,1,0,0,0,114,10,0,0, - 0,114,34,0,0,0,114,41,0,0,0,114,43,0,0,0, - 114,44,0,0,0,114,53,0,0,0,114,5,0,0,0,114, - 5,0,0,0,114,5,0,0,0,114,6,0,0,0,114,23, - 0,0,0,65,0,0,0,115,14,0,0,0,8,0,4,1, - 8,5,8,8,8,21,8,25,12,13,114,23,0,0,0,99, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 2,0,0,0,64,0,0,0,115,48,0,0,0,101,0,90, - 1,100,0,90,2,100,1,90,3,100,2,100,3,132,0,90, - 4,100,4,100,5,132,0,90,5,100,6,100,7,132,0,90, - 6,100,8,100,9,132,0,90,7,100,10,83,0,41,11,218, - 16,95,68,117,109,109,121,77,111,100,117,108,101,76,111,99, - 107,122,86,65,32,115,105,109,112,108,101,32,95,77,111,100, - 117,108,101,76,111,99,107,32,101,113,117,105,118,97,108,101, - 110,116,32,102,111,114,32,80,121,116,104,111,110,32,98,117, - 105,108,100,115,32,119,105,116,104,111,117,116,10,32,32,32, - 32,109,117,108,116,105,45,116,104,114,101,97,100,105,110,103, - 32,115,117,112,112,111,114,116,46,99,2,0,0,0,0,0, - 0,0,0,0,0,0,2,0,0,0,2,0,0,0,67,0, - 0,0,115,16,0,0,0,124,1,124,0,95,0,100,1,124, - 0,95,1,100,0,83,0,114,24,0,0,0,41,2,114,20, - 0,0,0,114,30,0,0,0,114,32,0,0,0,114,5,0, - 0,0,114,5,0,0,0,114,6,0,0,0,114,34,0,0, - 0,146,0,0,0,243,4,0,0,0,6,1,10,1,122,25, - 95,68,117,109,109,121,77,111,100,117,108,101,76,111,99,107, - 46,95,95,105,110,105,116,95,95,99,1,0,0,0,0,0, - 0,0,0,0,0,0,1,0,0,0,3,0,0,0,67,0, - 0,0,115,18,0,0,0,124,0,4,0,106,0,100,1,55, - 0,2,0,95,0,100,2,83,0,41,3,78,114,42,0,0, - 0,84,41,1,114,30,0,0,0,114,52,0,0,0,114,5, - 0,0,0,114,5,0,0,0,114,6,0,0,0,114,43,0, - 0,0,150,0,0,0,115,4,0,0,0,14,1,4,1,122, - 24,95,68,117,109,109,121,77,111,100,117,108,101,76,111,99, - 107,46,97,99,113,117,105,114,101,99,1,0,0,0,0,0, - 0,0,0,0,0,0,1,0,0,0,3,0,0,0,67,0, - 0,0,115,36,0,0,0,124,0,106,0,100,1,107,2,114, - 9,116,1,100,2,131,1,130,1,124,0,4,0,106,0,100, - 3,56,0,2,0,95,0,100,0,83,0,41,4,78,114,25, - 0,0,0,114,46,0,0,0,114,42,0,0,0,41,2,114, - 30,0,0,0,114,47,0,0,0,114,52,0,0,0,114,5, - 0,0,0,114,5,0,0,0,114,6,0,0,0,114,44,0, - 0,0,154,0,0,0,115,6,0,0,0,10,1,8,1,18, - 1,122,24,95,68,117,109,109,121,77,111,100,117,108,101,76, - 111,99,107,46,114,101,108,101,97,115,101,99,1,0,0,0, - 0,0,0,0,0,0,0,0,1,0,0,0,5,0,0,0, - 67,0,0,0,114,48,0,0,0,41,2,78,122,28,95,68, - 117,109,109,121,77,111,100,117,108,101,76,111,99,107,40,123, - 33,114,125,41,32,97,116,32,123,125,114,49,0,0,0,114, - 52,0,0,0,114,5,0,0,0,114,5,0,0,0,114,6, - 0,0,0,114,53,0,0,0,159,0,0,0,114,54,0,0, - 0,122,25,95,68,117,109,109,121,77,111,100,117,108,101,76, - 111,99,107,46,95,95,114,101,112,114,95,95,78,41,8,114, - 9,0,0,0,114,8,0,0,0,114,1,0,0,0,114,10, - 0,0,0,114,34,0,0,0,114,43,0,0,0,114,44,0, - 0,0,114,53,0,0,0,114,5,0,0,0,114,5,0,0, - 0,114,5,0,0,0,114,6,0,0,0,114,55,0,0,0, - 142,0,0,0,115,12,0,0,0,8,0,4,1,8,3,8, - 4,8,4,12,5,114,55,0,0,0,99,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,64, - 0,0,0,115,36,0,0,0,101,0,90,1,100,0,90,2, - 100,1,100,2,132,0,90,3,100,3,100,4,132,0,90,4, - 100,5,100,6,132,0,90,5,100,7,83,0,41,8,218,18, - 95,77,111,100,117,108,101,76,111,99,107,77,97,110,97,103, - 101,114,99,2,0,0,0,0,0,0,0,0,0,0,0,2, - 0,0,0,2,0,0,0,67,0,0,0,115,16,0,0,0, - 124,1,124,0,95,0,100,0,124,0,95,1,100,0,83,0, - 114,0,0,0,0,41,2,218,5,95,110,97,109,101,218,5, - 95,108,111,99,107,114,32,0,0,0,114,5,0,0,0,114, - 5,0,0,0,114,6,0,0,0,114,34,0,0,0,165,0, - 0,0,114,56,0,0,0,122,27,95,77,111,100,117,108,101, - 76,111,99,107,77,97,110,97,103,101,114,46,95,95,105,110, - 105,116,95,95,99,1,0,0,0,0,0,0,0,0,0,0, - 0,1,0,0,0,2,0,0,0,67,0,0,0,115,26,0, - 0,0,116,0,124,0,106,1,131,1,124,0,95,2,124,0, - 106,2,160,3,161,0,1,0,100,0,83,0,114,0,0,0, - 0,41,4,218,16,95,103,101,116,95,109,111,100,117,108,101, - 95,108,111,99,107,114,58,0,0,0,114,59,0,0,0,114, - 43,0,0,0,114,52,0,0,0,114,5,0,0,0,114,5, - 0,0,0,114,6,0,0,0,218,9,95,95,101,110,116,101, - 114,95,95,169,0,0,0,115,4,0,0,0,12,1,14,1, - 122,28,95,77,111,100,117,108,101,76,111,99,107,77,97,110, - 97,103,101,114,46,95,95,101,110,116,101,114,95,95,99,1, - 0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,2, - 0,0,0,79,0,0,0,115,14,0,0,0,124,0,106,0, - 160,1,161,0,1,0,100,0,83,0,114,0,0,0,0,41, - 2,114,59,0,0,0,114,44,0,0,0,41,3,114,33,0, - 0,0,218,4,97,114,103,115,90,6,107,119,97,114,103,115, - 114,5,0,0,0,114,5,0,0,0,114,6,0,0,0,218, - 8,95,95,101,120,105,116,95,95,173,0,0,0,115,2,0, - 0,0,14,1,122,27,95,77,111,100,117,108,101,76,111,99, - 107,77,97,110,97,103,101,114,46,95,95,101,120,105,116,95, - 95,78,41,6,114,9,0,0,0,114,8,0,0,0,114,1, - 0,0,0,114,34,0,0,0,114,61,0,0,0,114,63,0, - 0,0,114,5,0,0,0,114,5,0,0,0,114,5,0,0, - 0,114,6,0,0,0,114,57,0,0,0,163,0,0,0,115, - 8,0,0,0,8,0,8,2,8,4,12,4,114,57,0,0, - 0,99,1,0,0,0,0,0,0,0,0,0,0,0,3,0, - 0,0,8,0,0,0,67,0,0,0,115,148,0,0,0,116, - 0,160,1,161,0,1,0,122,64,122,7,116,2,124,0,25, - 0,131,0,125,1,87,0,110,11,4,0,116,3,121,23,1, - 0,1,0,1,0,100,1,125,1,89,0,110,1,119,0,124, - 1,100,1,117,0,114,62,116,4,100,1,117,0,114,37,116, - 5,124,0,131,1,125,1,110,4,116,6,124,0,131,1,125, - 1,124,0,102,1,100,2,100,3,132,1,125,2,116,7,160, - 8,124,1,124,2,161,2,116,2,124,0,60,0,87,0,116, - 0,160,9,161,0,1,0,124,1,83,0,87,0,116,0,160, - 9,161,0,1,0,124,1,83,0,116,0,160,9,161,0,1, - 0,119,0,41,4,122,139,71,101,116,32,111,114,32,99,114, - 101,97,116,101,32,116,104,101,32,109,111,100,117,108,101,32, - 108,111,99,107,32,102,111,114,32,97,32,103,105,118,101,110, - 32,109,111,100,117,108,101,32,110,97,109,101,46,10,10,32, - 32,32,32,65,99,113,117,105,114,101,47,114,101,108,101,97, - 115,101,32,105,110,116,101,114,110,97,108,108,121,32,116,104, - 101,32,103,108,111,98,97,108,32,105,109,112,111,114,116,32, - 108,111,99,107,32,116,111,32,112,114,111,116,101,99,116,10, - 32,32,32,32,95,109,111,100,117,108,101,95,108,111,99,107, - 115,46,78,99,2,0,0,0,0,0,0,0,0,0,0,0, - 2,0,0,0,8,0,0,0,83,0,0,0,115,68,0,0, - 0,116,0,160,1,161,0,1,0,122,24,116,2,160,3,124, - 1,161,1,124,0,117,0,114,22,116,2,124,1,61,0,87, - 0,116,0,160,4,161,0,1,0,100,0,83,0,87,0,116, - 0,160,4,161,0,1,0,100,0,83,0,116,0,160,4,161, - 0,1,0,119,0,114,0,0,0,0,41,5,218,4,95,105, - 109,112,218,12,97,99,113,117,105,114,101,95,108,111,99,107, - 218,13,95,109,111,100,117,108,101,95,108,111,99,107,115,114, - 38,0,0,0,218,12,114,101,108,101,97,115,101,95,108,111, - 99,107,41,2,218,3,114,101,102,114,20,0,0,0,114,5, - 0,0,0,114,5,0,0,0,114,6,0,0,0,218,2,99, - 98,198,0,0,0,115,14,0,0,0,8,1,2,1,14,4, - 8,1,12,2,2,253,22,3,122,28,95,103,101,116,95,109, - 111,100,117,108,101,95,108,111,99,107,46,60,108,111,99,97, - 108,115,62,46,99,98,41,10,114,64,0,0,0,114,65,0, - 0,0,114,66,0,0,0,218,8,75,101,121,69,114,114,111, - 114,114,26,0,0,0,114,55,0,0,0,114,23,0,0,0, - 218,8,95,119,101,97,107,114,101,102,114,68,0,0,0,114, - 67,0,0,0,41,3,114,20,0,0,0,114,27,0,0,0, - 114,69,0,0,0,114,5,0,0,0,114,5,0,0,0,114, - 6,0,0,0,114,60,0,0,0,179,0,0,0,115,38,0, - 0,0,8,6,2,1,2,1,14,1,12,1,8,1,2,255, - 8,3,8,1,10,1,8,2,12,2,18,11,8,2,4,2, - 2,235,8,19,4,2,10,254,114,60,0,0,0,99,1,0, - 0,0,0,0,0,0,0,0,0,0,2,0,0,0,8,0, - 0,0,67,0,0,0,115,54,0,0,0,116,0,124,0,131, - 1,125,1,122,6,124,1,160,1,161,0,1,0,87,0,110, - 10,4,0,116,2,121,20,1,0,1,0,1,0,89,0,100, - 1,83,0,119,0,124,1,160,3,161,0,1,0,100,1,83, - 0,41,2,122,189,65,99,113,117,105,114,101,115,32,116,104, - 101,110,32,114,101,108,101,97,115,101,115,32,116,104,101,32, - 109,111,100,117,108,101,32,108,111,99,107,32,102,111,114,32, - 97,32,103,105,118,101,110,32,109,111,100,117,108,101,32,110, - 97,109,101,46,10,10,32,32,32,32,84,104,105,115,32,105, - 115,32,117,115,101,100,32,116,111,32,101,110,115,117,114,101, - 32,97,32,109,111,100,117,108,101,32,105,115,32,99,111,109, - 112,108,101,116,101,108,121,32,105,110,105,116,105,97,108,105, - 122,101,100,44,32,105,110,32,116,104,101,10,32,32,32,32, - 101,118,101,110,116,32,105,116,32,105,115,32,98,101,105,110, - 103,32,105,109,112,111,114,116,101,100,32,98,121,32,97,110, - 111,116,104,101,114,32,116,104,114,101,97,100,46,10,32,32, - 32,32,78,41,4,114,60,0,0,0,114,43,0,0,0,114, - 22,0,0,0,114,44,0,0,0,41,2,114,20,0,0,0, - 114,27,0,0,0,114,5,0,0,0,114,5,0,0,0,114, - 6,0,0,0,218,19,95,108,111,99,107,95,117,110,108,111, - 99,107,95,109,111,100,117,108,101,216,0,0,0,115,14,0, - 0,0,8,6,2,1,12,1,12,1,6,3,2,253,12,5, - 114,72,0,0,0,99,1,0,0,0,0,0,0,0,0,0, - 0,0,3,0,0,0,4,0,0,0,79,0,0,0,115,14, - 0,0,0,124,0,124,1,105,0,124,2,164,1,142,1,83, - 0,41,1,97,46,1,0,0,114,101,109,111,118,101,95,105, - 109,112,111,114,116,108,105,98,95,102,114,97,109,101,115,32, - 105,110,32,105,109,112,111,114,116,46,99,32,119,105,108,108, - 32,97,108,119,97,121,115,32,114,101,109,111,118,101,32,115, - 101,113,117,101,110,99,101,115,10,32,32,32,32,111,102,32, - 105,109,112,111,114,116,108,105,98,32,102,114,97,109,101,115, - 32,116,104,97,116,32,101,110,100,32,119,105,116,104,32,97, - 32,99,97,108,108,32,116,111,32,116,104,105,115,32,102,117, - 110,99,116,105,111,110,10,10,32,32,32,32,85,115,101,32, - 105,116,32,105,110,115,116,101,97,100,32,111,102,32,97,32, - 110,111,114,109,97,108,32,99,97,108,108,32,105,110,32,112, - 108,97,99,101,115,32,119,104,101,114,101,32,105,110,99,108, - 117,100,105,110,103,32,116,104,101,32,105,109,112,111,114,116, - 108,105,98,10,32,32,32,32,102,114,97,109,101,115,32,105, - 110,116,114,111,100,117,99,101,115,32,117,110,119,97,110,116, - 101,100,32,110,111,105,115,101,32,105,110,116,111,32,116,104, - 101,32,116,114,97,99,101,98,97,99,107,32,40,101,46,103, - 46,32,119,104,101,110,32,101,120,101,99,117,116,105,110,103, - 10,32,32,32,32,109,111,100,117,108,101,32,99,111,100,101, - 41,10,32,32,32,32,114,5,0,0,0,41,3,218,1,102, - 114,62,0,0,0,90,4,107,119,100,115,114,5,0,0,0, - 114,5,0,0,0,114,6,0,0,0,218,25,95,99,97,108, - 108,95,119,105,116,104,95,102,114,97,109,101,115,95,114,101, - 109,111,118,101,100,233,0,0,0,115,2,0,0,0,14,8, - 114,74,0,0,0,114,42,0,0,0,41,1,218,9,118,101, - 114,98,111,115,105,116,121,99,1,0,0,0,0,0,0,0, - 1,0,0,0,3,0,0,0,4,0,0,0,71,0,0,0, - 115,58,0,0,0,116,0,106,1,106,2,124,1,107,5,114, - 27,124,0,160,3,100,1,161,1,115,15,100,2,124,0,23, - 0,125,0,116,4,124,0,106,5,124,2,142,0,116,0,106, - 6,100,3,141,2,1,0,100,4,83,0,100,4,83,0,41, - 5,122,61,80,114,105,110,116,32,116,104,101,32,109,101,115, - 115,97,103,101,32,116,111,32,115,116,100,101,114,114,32,105, - 102,32,45,118,47,80,89,84,72,79,78,86,69,82,66,79, - 83,69,32,105,115,32,116,117,114,110,101,100,32,111,110,46, - 41,2,250,1,35,122,7,105,109,112,111,114,116,32,122,2, - 35,32,41,1,90,4,102,105,108,101,78,41,7,114,18,0, - 0,0,218,5,102,108,97,103,115,218,7,118,101,114,98,111, - 115,101,218,10,115,116,97,114,116,115,119,105,116,104,218,5, - 112,114,105,110,116,114,50,0,0,0,218,6,115,116,100,101, - 114,114,41,3,218,7,109,101,115,115,97,103,101,114,75,0, - 0,0,114,62,0,0,0,114,5,0,0,0,114,5,0,0, - 0,114,6,0,0,0,218,16,95,118,101,114,98,111,115,101, - 95,109,101,115,115,97,103,101,244,0,0,0,115,10,0,0, - 0,12,2,10,1,8,1,24,1,4,253,114,83,0,0,0, - 99,1,0,0,0,0,0,0,0,0,0,0,0,2,0,0, - 0,3,0,0,0,3,0,0,0,243,26,0,0,0,135,0, - 102,1,100,1,100,2,132,8,125,1,116,0,124,1,136,0, - 131,2,1,0,124,1,83,0,41,3,122,49,68,101,99,111, - 114,97,116,111,114,32,116,111,32,118,101,114,105,102,121,32, - 116,104,101,32,110,97,109,101,100,32,109,111,100,117,108,101, - 32,105,115,32,98,117,105,108,116,45,105,110,46,99,2,0, - 0,0,0,0,0,0,0,0,0,0,2,0,0,0,4,0, - 0,0,19,0,0,0,115,38,0,0,0,124,1,116,0,106, - 1,118,1,114,14,116,2,100,1,160,3,124,1,161,1,124, - 1,100,2,141,2,130,1,136,0,124,0,124,1,131,2,83, - 0,41,3,78,250,29,123,33,114,125,32,105,115,32,110,111, - 116,32,97,32,98,117,105,108,116,45,105,110,32,109,111,100, - 117,108,101,114,19,0,0,0,41,4,114,18,0,0,0,218, - 20,98,117,105,108,116,105,110,95,109,111,100,117,108,101,95, - 110,97,109,101,115,218,11,73,109,112,111,114,116,69,114,114, - 111,114,114,50,0,0,0,169,2,114,33,0,0,0,218,8, - 102,117,108,108,110,97,109,101,169,1,218,3,102,120,110,114, - 5,0,0,0,114,6,0,0,0,218,25,95,114,101,113,117, - 105,114,101,115,95,98,117,105,108,116,105,110,95,119,114,97, - 112,112,101,114,254,0,0,0,243,10,0,0,0,10,1,10, - 1,2,1,6,255,10,2,122,52,95,114,101,113,117,105,114, - 101,115,95,98,117,105,108,116,105,110,46,60,108,111,99,97, - 108,115,62,46,95,114,101,113,117,105,114,101,115,95,98,117, - 105,108,116,105,110,95,119,114,97,112,112,101,114,169,1,114, - 17,0,0,0,41,2,114,91,0,0,0,114,92,0,0,0, - 114,5,0,0,0,114,90,0,0,0,114,6,0,0,0,218, - 17,95,114,101,113,117,105,114,101,115,95,98,117,105,108,116, - 105,110,252,0,0,0,243,6,0,0,0,12,2,10,5,4, - 1,114,95,0,0,0,99,1,0,0,0,0,0,0,0,0, - 0,0,0,2,0,0,0,3,0,0,0,3,0,0,0,114, - 84,0,0,0,41,3,122,47,68,101,99,111,114,97,116,111, - 114,32,116,111,32,118,101,114,105,102,121,32,116,104,101,32, - 110,97,109,101,100,32,109,111,100,117,108,101,32,105,115,32, - 102,114,111,122,101,110,46,99,2,0,0,0,0,0,0,0, - 0,0,0,0,2,0,0,0,4,0,0,0,19,0,0,0, - 115,38,0,0,0,116,0,160,1,124,1,161,1,115,14,116, - 2,100,1,160,3,124,1,161,1,124,1,100,2,141,2,130, - 1,136,0,124,0,124,1,131,2,83,0,169,3,78,122,27, - 123,33,114,125,32,105,115,32,110,111,116,32,97,32,102,114, - 111,122,101,110,32,109,111,100,117,108,101,114,19,0,0,0, - 41,4,114,64,0,0,0,218,9,105,115,95,102,114,111,122, - 101,110,114,87,0,0,0,114,50,0,0,0,114,88,0,0, - 0,114,90,0,0,0,114,5,0,0,0,114,6,0,0,0, - 218,24,95,114,101,113,117,105,114,101,115,95,102,114,111,122, - 101,110,95,119,114,97,112,112,101,114,9,1,0,0,114,93, - 0,0,0,122,50,95,114,101,113,117,105,114,101,115,95,102, - 114,111,122,101,110,46,60,108,111,99,97,108,115,62,46,95, - 114,101,113,117,105,114,101,115,95,102,114,111,122,101,110,95, - 119,114,97,112,112,101,114,114,94,0,0,0,41,2,114,91, - 0,0,0,114,99,0,0,0,114,5,0,0,0,114,90,0, - 0,0,114,6,0,0,0,218,16,95,114,101,113,117,105,114, - 101,115,95,102,114,111,122,101,110,7,1,0,0,114,96,0, - 0,0,114,100,0,0,0,99,2,0,0,0,0,0,0,0, - 0,0,0,0,5,0,0,0,4,0,0,0,67,0,0,0, - 115,74,0,0,0,100,1,125,2,116,0,160,1,124,2,116, - 2,161,2,1,0,116,3,124,1,124,0,131,2,125,3,124, - 1,116,4,106,5,118,0,114,33,116,4,106,5,124,1,25, - 0,125,4,116,6,124,3,124,4,131,2,1,0,116,4,106, - 5,124,1,25,0,83,0,116,7,124,3,131,1,83,0,41, - 2,122,130,76,111,97,100,32,116,104,101,32,115,112,101,99, - 105,102,105,101,100,32,109,111,100,117,108,101,32,105,110,116, - 111,32,115,121,115,46,109,111,100,117,108,101,115,32,97,110, - 100,32,114,101,116,117,114,110,32,105,116,46,10,10,32,32, - 32,32,84,104,105,115,32,109,101,116,104,111,100,32,105,115, - 32,100,101,112,114,101,99,97,116,101,100,46,32,32,85,115, - 101,32,108,111,97,100,101,114,46,101,120,101,99,95,109,111, - 100,117,108,101,40,41,32,105,110,115,116,101,97,100,46,10, - 10,32,32,32,32,122,103,116,104,101,32,108,111,97,100,95, - 109,111,100,117,108,101,40,41,32,109,101,116,104,111,100,32, - 105,115,32,100,101,112,114,101,99,97,116,101,100,32,97,110, - 100,32,115,108,97,116,101,100,32,102,111,114,32,114,101,109, - 111,118,97,108,32,105,110,32,80,121,116,104,111,110,32,51, - 46,49,50,59,32,117,115,101,32,101,120,101,99,95,109,111, - 100,117,108,101,40,41,32,105,110,115,116,101,97,100,41,8, - 218,9,95,119,97,114,110,105,110,103,115,218,4,119,97,114, - 110,218,18,68,101,112,114,101,99,97,116,105,111,110,87,97, - 114,110,105,110,103,218,16,115,112,101,99,95,102,114,111,109, - 95,108,111,97,100,101,114,114,18,0,0,0,218,7,109,111, - 100,117,108,101,115,218,5,95,101,120,101,99,218,5,95,108, - 111,97,100,41,5,114,33,0,0,0,114,89,0,0,0,218, - 3,109,115,103,218,4,115,112,101,99,218,6,109,111,100,117, - 108,101,114,5,0,0,0,114,5,0,0,0,114,6,0,0, - 0,218,17,95,108,111,97,100,95,109,111,100,117,108,101,95, - 115,104,105,109,19,1,0,0,115,16,0,0,0,4,6,12, - 2,10,1,10,1,10,1,10,1,10,1,8,2,114,111,0, - 0,0,99,1,0,0,0,0,0,0,0,0,0,0,0,5, - 0,0,0,8,0,0,0,67,0,0,0,115,188,0,0,0, - 116,0,124,0,100,1,100,2,131,3,125,1,116,0,124,0, - 100,3,100,2,131,3,4,0,125,2,114,18,116,1,124,2, - 131,1,83,0,116,2,124,1,100,4,131,2,114,39,122,6, - 124,1,160,3,124,0,161,1,87,0,83,0,4,0,116,4, - 121,38,1,0,1,0,1,0,89,0,110,1,119,0,122,5, - 124,0,106,5,125,3,87,0,110,11,4,0,116,6,121,55, - 1,0,1,0,1,0,100,5,125,3,89,0,110,1,119,0, - 122,5,124,0,106,7,125,4,87,0,110,26,4,0,116,6, - 121,87,1,0,1,0,1,0,124,1,100,2,117,0,114,79, - 100,6,160,8,124,3,161,1,6,0,89,0,83,0,100,7, - 160,8,124,3,124,1,161,2,6,0,89,0,83,0,119,0, - 100,8,160,8,124,3,124,4,161,2,83,0,41,9,122,44, - 84,104,101,32,105,109,112,108,101,109,101,110,116,97,116,105, - 111,110,32,111,102,32,77,111,100,117,108,101,84,121,112,101, - 46,95,95,114,101,112,114,95,95,40,41,46,218,10,95,95, - 108,111,97,100,101,114,95,95,78,218,8,95,95,115,112,101, - 99,95,95,218,11,109,111,100,117,108,101,95,114,101,112,114, - 250,1,63,250,13,60,109,111,100,117,108,101,32,123,33,114, - 125,62,250,20,60,109,111,100,117,108,101,32,123,33,114,125, - 32,40,123,33,114,125,41,62,250,23,60,109,111,100,117,108, - 101,32,123,33,114,125,32,102,114,111,109,32,123,33,114,125, - 62,41,9,114,13,0,0,0,218,22,95,109,111,100,117,108, - 101,95,114,101,112,114,95,102,114,111,109,95,115,112,101,99, - 114,11,0,0,0,114,114,0,0,0,218,9,69,120,99,101, - 112,116,105,111,110,114,9,0,0,0,114,2,0,0,0,218, - 8,95,95,102,105,108,101,95,95,114,50,0,0,0,41,5, - 114,110,0,0,0,218,6,108,111,97,100,101,114,114,109,0, - 0,0,114,20,0,0,0,218,8,102,105,108,101,110,97,109, - 101,114,5,0,0,0,114,5,0,0,0,114,6,0,0,0, - 218,12,95,109,111,100,117,108,101,95,114,101,112,114,38,1, - 0,0,115,44,0,0,0,12,2,16,1,8,1,10,1,2, - 1,12,1,12,1,4,1,2,255,2,3,10,1,12,1,8, - 1,2,255,2,2,10,1,12,1,8,1,14,1,16,2,2, - 252,12,6,114,124,0,0,0,99,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,4,0,0,0,64,0,0, - 0,115,114,0,0,0,101,0,90,1,100,0,90,2,100,1, - 90,3,100,2,100,2,100,2,100,3,156,3,100,4,100,5, - 132,2,90,4,100,6,100,7,132,0,90,5,100,8,100,9, - 132,0,90,6,101,7,100,10,100,11,132,0,131,1,90,8, - 101,8,106,9,100,12,100,11,132,0,131,1,90,8,101,7, - 100,13,100,14,132,0,131,1,90,10,101,7,100,15,100,16, - 132,0,131,1,90,11,101,11,106,9,100,17,100,16,132,0, - 131,1,90,11,100,2,83,0,41,18,218,10,77,111,100,117, - 108,101,83,112,101,99,97,208,5,0,0,84,104,101,32,115, - 112,101,99,105,102,105,99,97,116,105,111,110,32,102,111,114, - 32,97,32,109,111,100,117,108,101,44,32,117,115,101,100,32, - 102,111,114,32,108,111,97,100,105,110,103,46,10,10,32,32, - 32,32,65,32,109,111,100,117,108,101,39,115,32,115,112,101, - 99,32,105,115,32,116,104,101,32,115,111,117,114,99,101,32, - 102,111,114,32,105,110,102,111,114,109,97,116,105,111,110,32, - 97,98,111,117,116,32,116,104,101,32,109,111,100,117,108,101, - 46,32,32,70,111,114,10,32,32,32,32,100,97,116,97,32, - 97,115,115,111,99,105,97,116,101,100,32,119,105,116,104,32, - 116,104,101,32,109,111,100,117,108,101,44,32,105,110,99,108, - 117,100,105,110,103,32,115,111,117,114,99,101,44,32,117,115, - 101,32,116,104,101,32,115,112,101,99,39,115,10,32,32,32, - 32,108,111,97,100,101,114,46,10,10,32,32,32,32,96,110, - 97,109,101,96,32,105,115,32,116,104,101,32,97,98,115,111, - 108,117,116,101,32,110,97,109,101,32,111,102,32,116,104,101, - 32,109,111,100,117,108,101,46,32,32,96,108,111,97,100,101, - 114,96,32,105,115,32,116,104,101,32,108,111,97,100,101,114, - 10,32,32,32,32,116,111,32,117,115,101,32,119,104,101,110, - 32,108,111,97,100,105,110,103,32,116,104,101,32,109,111,100, - 117,108,101,46,32,32,96,112,97,114,101,110,116,96,32,105, - 115,32,116,104,101,32,110,97,109,101,32,111,102,32,116,104, - 101,10,32,32,32,32,112,97,99,107,97,103,101,32,116,104, - 101,32,109,111,100,117,108,101,32,105,115,32,105,110,46,32, - 32,84,104,101,32,112,97,114,101,110,116,32,105,115,32,100, - 101,114,105,118,101,100,32,102,114,111,109,32,116,104,101,32, - 110,97,109,101,46,10,10,32,32,32,32,96,105,115,95,112, - 97,99,107,97,103,101,96,32,100,101,116,101,114,109,105,110, - 101,115,32,105,102,32,116,104,101,32,109,111,100,117,108,101, - 32,105,115,32,99,111,110,115,105,100,101,114,101,100,32,97, - 32,112,97,99,107,97,103,101,32,111,114,10,32,32,32,32, - 110,111,116,46,32,32,79,110,32,109,111,100,117,108,101,115, - 32,116,104,105,115,32,105,115,32,114,101,102,108,101,99,116, - 101,100,32,98,121,32,116,104,101,32,96,95,95,112,97,116, - 104,95,95,96,32,97,116,116,114,105,98,117,116,101,46,10, - 10,32,32,32,32,96,111,114,105,103,105,110,96,32,105,115, - 32,116,104,101,32,115,112,101,99,105,102,105,99,32,108,111, - 99,97,116,105,111,110,32,117,115,101,100,32,98,121,32,116, - 104,101,32,108,111,97,100,101,114,32,102,114,111,109,32,119, - 104,105,99,104,32,116,111,10,32,32,32,32,108,111,97,100, - 32,116,104,101,32,109,111,100,117,108,101,44,32,105,102,32, - 116,104,97,116,32,105,110,102,111,114,109,97,116,105,111,110, - 32,105,115,32,97,118,97,105,108,97,98,108,101,46,32,32, - 87,104,101,110,32,102,105,108,101,110,97,109,101,32,105,115, - 10,32,32,32,32,115,101,116,44,32,111,114,105,103,105,110, - 32,119,105,108,108,32,109,97,116,99,104,46,10,10,32,32, - 32,32,96,104,97,115,95,108,111,99,97,116,105,111,110,96, - 32,105,110,100,105,99,97,116,101,115,32,116,104,97,116,32, - 97,32,115,112,101,99,39,115,32,34,111,114,105,103,105,110, - 34,32,114,101,102,108,101,99,116,115,32,97,32,108,111,99, - 97,116,105,111,110,46,10,32,32,32,32,87,104,101,110,32, - 116,104,105,115,32,105,115,32,84,114,117,101,44,32,96,95, - 95,102,105,108,101,95,95,96,32,97,116,116,114,105,98,117, - 116,101,32,111,102,32,116,104,101,32,109,111,100,117,108,101, - 32,105,115,32,115,101,116,46,10,10,32,32,32,32,96,99, - 97,99,104,101,100,96,32,105,115,32,116,104,101,32,108,111, - 99,97,116,105,111,110,32,111,102,32,116,104,101,32,99,97, - 99,104,101,100,32,98,121,116,101,99,111,100,101,32,102,105, - 108,101,44,32,105,102,32,97,110,121,46,32,32,73,116,10, - 32,32,32,32,99,111,114,114,101,115,112,111,110,100,115,32, - 116,111,32,116,104,101,32,96,95,95,99,97,99,104,101,100, - 95,95,96,32,97,116,116,114,105,98,117,116,101,46,10,10, - 32,32,32,32,96,115,117,98,109,111,100,117,108,101,95,115, - 101,97,114,99,104,95,108,111,99,97,116,105,111,110,115,96, - 32,105,115,32,116,104,101,32,115,101,113,117,101,110,99,101, - 32,111,102,32,112,97,116,104,32,101,110,116,114,105,101,115, - 32,116,111,10,32,32,32,32,115,101,97,114,99,104,32,119, - 104,101,110,32,105,109,112,111,114,116,105,110,103,32,115,117, - 98,109,111,100,117,108,101,115,46,32,32,73,102,32,115,101, - 116,44,32,105,115,95,112,97,99,107,97,103,101,32,115,104, - 111,117,108,100,32,98,101,10,32,32,32,32,84,114,117,101, - 45,45,97,110,100,32,70,97,108,115,101,32,111,116,104,101, - 114,119,105,115,101,46,10,10,32,32,32,32,80,97,99,107, - 97,103,101,115,32,97,114,101,32,115,105,109,112,108,121,32, - 109,111,100,117,108,101,115,32,116,104,97,116,32,40,109,97, - 121,41,32,104,97,118,101,32,115,117,98,109,111,100,117,108, - 101,115,46,32,32,73,102,32,97,32,115,112,101,99,10,32, - 32,32,32,104,97,115,32,97,32,110,111,110,45,78,111,110, - 101,32,118,97,108,117,101,32,105,110,32,96,115,117,98,109, - 111,100,117,108,101,95,115,101,97,114,99,104,95,108,111,99, - 97,116,105,111,110,115,96,44,32,116,104,101,32,105,109,112, - 111,114,116,10,32,32,32,32,115,121,115,116,101,109,32,119, - 105,108,108,32,99,111,110,115,105,100,101,114,32,109,111,100, - 117,108,101,115,32,108,111,97,100,101,100,32,102,114,111,109, - 32,116,104,101,32,115,112,101,99,32,97,115,32,112,97,99, - 107,97,103,101,115,46,10,10,32,32,32,32,79,110,108,121, - 32,102,105,110,100,101,114,115,32,40,115,101,101,32,105,109, - 112,111,114,116,108,105,98,46,97,98,99,46,77,101,116,97, - 80,97,116,104,70,105,110,100,101,114,32,97,110,100,10,32, - 32,32,32,105,109,112,111,114,116,108,105,98,46,97,98,99, - 46,80,97,116,104,69,110,116,114,121,70,105,110,100,101,114, - 41,32,115,104,111,117,108,100,32,109,111,100,105,102,121,32, - 77,111,100,117,108,101,83,112,101,99,32,105,110,115,116,97, - 110,99,101,115,46,10,10,32,32,32,32,78,41,3,218,6, - 111,114,105,103,105,110,218,12,108,111,97,100,101,114,95,115, - 116,97,116,101,218,10,105,115,95,112,97,99,107,97,103,101, - 99,3,0,0,0,0,0,0,0,3,0,0,0,6,0,0, - 0,2,0,0,0,67,0,0,0,115,54,0,0,0,124,1, - 124,0,95,0,124,2,124,0,95,1,124,3,124,0,95,2, - 124,4,124,0,95,3,124,5,114,16,103,0,110,1,100,0, - 124,0,95,4,100,1,124,0,95,5,100,0,124,0,95,6, - 100,0,83,0,41,2,78,70,41,7,114,20,0,0,0,114, - 122,0,0,0,114,126,0,0,0,114,127,0,0,0,218,26, - 115,117,98,109,111,100,117,108,101,95,115,101,97,114,99,104, - 95,108,111,99,97,116,105,111,110,115,218,13,95,115,101,116, - 95,102,105,108,101,97,116,116,114,218,7,95,99,97,99,104, - 101,100,41,6,114,33,0,0,0,114,20,0,0,0,114,122, - 0,0,0,114,126,0,0,0,114,127,0,0,0,114,128,0, - 0,0,114,5,0,0,0,114,5,0,0,0,114,6,0,0, - 0,114,34,0,0,0,101,1,0,0,115,14,0,0,0,6, - 2,6,1,6,1,6,1,14,1,6,3,10,1,122,19,77, - 111,100,117,108,101,83,112,101,99,46,95,95,105,110,105,116, - 95,95,99,1,0,0,0,0,0,0,0,0,0,0,0,2, - 0,0,0,6,0,0,0,67,0,0,0,115,102,0,0,0, - 100,1,160,0,124,0,106,1,161,1,100,2,160,0,124,0, - 106,2,161,1,103,2,125,1,124,0,106,3,100,0,117,1, - 114,26,124,1,160,4,100,3,160,0,124,0,106,3,161,1, - 161,1,1,0,124,0,106,5,100,0,117,1,114,40,124,1, - 160,4,100,4,160,0,124,0,106,5,161,1,161,1,1,0, - 100,5,160,0,124,0,106,6,106,7,100,6,160,8,124,1, - 161,1,161,2,83,0,41,7,78,122,9,110,97,109,101,61, - 123,33,114,125,122,11,108,111,97,100,101,114,61,123,33,114, - 125,122,11,111,114,105,103,105,110,61,123,33,114,125,122,29, - 115,117,98,109,111,100,117,108,101,95,115,101,97,114,99,104, - 95,108,111,99,97,116,105,111,110,115,61,123,125,122,6,123, - 125,40,123,125,41,122,2,44,32,41,9,114,50,0,0,0, - 114,20,0,0,0,114,122,0,0,0,114,126,0,0,0,218, - 6,97,112,112,101,110,100,114,129,0,0,0,218,9,95,95, - 99,108,97,115,115,95,95,114,9,0,0,0,218,4,106,111, - 105,110,41,2,114,33,0,0,0,114,62,0,0,0,114,5, - 0,0,0,114,5,0,0,0,114,6,0,0,0,114,53,0, - 0,0,113,1,0,0,115,20,0,0,0,10,1,10,1,4, - 255,10,2,18,1,10,1,6,1,8,1,4,255,22,2,122, - 19,77,111,100,117,108,101,83,112,101,99,46,95,95,114,101, - 112,114,95,95,99,2,0,0,0,0,0,0,0,0,0,0, - 0,3,0,0,0,8,0,0,0,67,0,0,0,115,102,0, - 0,0,124,0,106,0,125,2,122,36,124,0,106,1,124,1, - 106,1,107,2,111,38,124,0,106,2,124,1,106,2,107,2, - 111,38,124,0,106,3,124,1,106,3,107,2,111,38,124,2, - 124,1,106,0,107,2,111,38,124,0,106,4,124,1,106,4, - 107,2,111,38,124,0,106,5,124,1,106,5,107,2,87,0, - 83,0,4,0,116,6,121,50,1,0,1,0,1,0,116,7, - 6,0,89,0,83,0,119,0,114,0,0,0,0,41,8,114, - 129,0,0,0,114,20,0,0,0,114,122,0,0,0,114,126, - 0,0,0,218,6,99,97,99,104,101,100,218,12,104,97,115, - 95,108,111,99,97,116,105,111,110,114,2,0,0,0,218,14, - 78,111,116,73,109,112,108,101,109,101,110,116,101,100,41,3, - 114,33,0,0,0,90,5,111,116,104,101,114,90,4,115,109, - 115,108,114,5,0,0,0,114,5,0,0,0,114,6,0,0, - 0,218,6,95,95,101,113,95,95,123,1,0,0,115,32,0, - 0,0,6,1,2,1,12,1,10,1,2,255,10,2,2,254, - 8,3,2,253,10,4,2,252,10,5,4,251,12,6,8,1, - 2,255,122,17,77,111,100,117,108,101,83,112,101,99,46,95, - 95,101,113,95,95,99,1,0,0,0,0,0,0,0,0,0, - 0,0,1,0,0,0,3,0,0,0,67,0,0,0,115,58, - 0,0,0,124,0,106,0,100,0,117,0,114,26,124,0,106, - 1,100,0,117,1,114,26,124,0,106,2,114,26,116,3,100, - 0,117,0,114,19,116,4,130,1,116,3,160,5,124,0,106, - 1,161,1,124,0,95,0,124,0,106,0,83,0,114,0,0, - 0,0,41,6,114,131,0,0,0,114,126,0,0,0,114,130, - 0,0,0,218,19,95,98,111,111,116,115,116,114,97,112,95, - 101,120,116,101,114,110,97,108,218,19,78,111,116,73,109,112, - 108,101,109,101,110,116,101,100,69,114,114,111,114,90,11,95, - 103,101,116,95,99,97,99,104,101,100,114,52,0,0,0,114, - 5,0,0,0,114,5,0,0,0,114,6,0,0,0,114,135, - 0,0,0,135,1,0,0,115,12,0,0,0,10,2,16,1, - 8,1,4,1,14,1,6,1,122,17,77,111,100,117,108,101, - 83,112,101,99,46,99,97,99,104,101,100,99,2,0,0,0, - 0,0,0,0,0,0,0,0,2,0,0,0,2,0,0,0, - 67,0,0,0,115,10,0,0,0,124,1,124,0,95,0,100, - 0,83,0,114,0,0,0,0,41,1,114,131,0,0,0,41, - 2,114,33,0,0,0,114,135,0,0,0,114,5,0,0,0, - 114,5,0,0,0,114,6,0,0,0,114,135,0,0,0,144, - 1,0,0,115,2,0,0,0,10,2,99,1,0,0,0,0, - 0,0,0,0,0,0,0,1,0,0,0,3,0,0,0,67, - 0,0,0,115,32,0,0,0,124,0,106,0,100,1,117,0, - 114,13,124,0,106,1,160,2,100,2,161,1,100,3,25,0, - 83,0,124,0,106,1,83,0,41,4,122,32,84,104,101,32, - 110,97,109,101,32,111,102,32,116,104,101,32,109,111,100,117, - 108,101,39,115,32,112,97,114,101,110,116,46,78,218,1,46, - 114,25,0,0,0,41,3,114,129,0,0,0,114,20,0,0, - 0,218,10,114,112,97,114,116,105,116,105,111,110,114,52,0, - 0,0,114,5,0,0,0,114,5,0,0,0,114,6,0,0, - 0,218,6,112,97,114,101,110,116,148,1,0,0,115,6,0, - 0,0,10,3,16,1,6,2,122,17,77,111,100,117,108,101, - 83,112,101,99,46,112,97,114,101,110,116,99,1,0,0,0, - 0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0, - 67,0,0,0,115,6,0,0,0,124,0,106,0,83,0,114, - 0,0,0,0,41,1,114,130,0,0,0,114,52,0,0,0, - 114,5,0,0,0,114,5,0,0,0,114,6,0,0,0,114, - 136,0,0,0,156,1,0,0,115,2,0,0,0,6,2,122, - 23,77,111,100,117,108,101,83,112,101,99,46,104,97,115,95, - 108,111,99,97,116,105,111,110,99,2,0,0,0,0,0,0, - 0,0,0,0,0,2,0,0,0,2,0,0,0,67,0,0, - 0,115,14,0,0,0,116,0,124,1,131,1,124,0,95,1, - 100,0,83,0,114,0,0,0,0,41,2,218,4,98,111,111, - 108,114,130,0,0,0,41,2,114,33,0,0,0,218,5,118, - 97,108,117,101,114,5,0,0,0,114,5,0,0,0,114,6, - 0,0,0,114,136,0,0,0,160,1,0,0,115,2,0,0, - 0,14,2,41,12,114,9,0,0,0,114,8,0,0,0,114, - 1,0,0,0,114,10,0,0,0,114,34,0,0,0,114,53, - 0,0,0,114,138,0,0,0,218,8,112,114,111,112,101,114, - 116,121,114,135,0,0,0,218,6,115,101,116,116,101,114,114, - 143,0,0,0,114,136,0,0,0,114,5,0,0,0,114,5, - 0,0,0,114,5,0,0,0,114,6,0,0,0,114,125,0, - 0,0,64,1,0,0,115,34,0,0,0,8,0,4,1,4, - 36,2,1,12,255,8,12,8,10,2,12,10,1,4,8,10, - 1,2,3,10,1,2,7,10,1,4,3,14,1,114,125,0, - 0,0,169,2,114,126,0,0,0,114,128,0,0,0,99,2, - 0,0,0,0,0,0,0,2,0,0,0,6,0,0,0,8, - 0,0,0,67,0,0,0,115,150,0,0,0,116,0,124,1, - 100,1,131,2,114,37,116,1,100,2,117,0,114,11,116,2, - 130,1,116,1,106,3,125,4,124,3,100,2,117,0,114,24, - 124,4,124,0,124,1,100,3,141,2,83,0,124,3,114,28, - 103,0,110,1,100,2,125,5,124,4,124,0,124,1,124,5, - 100,4,141,3,83,0,124,3,100,2,117,0,114,67,116,0, - 124,1,100,5,131,2,114,65,122,7,124,1,160,4,124,0, - 161,1,125,3,87,0,110,13,4,0,116,5,121,64,1,0, - 1,0,1,0,100,2,125,3,89,0,110,3,119,0,100,6, - 125,3,116,6,124,0,124,1,124,2,124,3,100,7,141,4, - 83,0,41,8,122,53,82,101,116,117,114,110,32,97,32,109, - 111,100,117,108,101,32,115,112,101,99,32,98,97,115,101,100, - 32,111,110,32,118,97,114,105,111,117,115,32,108,111,97,100, - 101,114,32,109,101,116,104,111,100,115,46,90,12,103,101,116, - 95,102,105,108,101,110,97,109,101,78,41,1,114,122,0,0, - 0,41,2,114,122,0,0,0,114,129,0,0,0,114,128,0, - 0,0,70,114,148,0,0,0,41,7,114,11,0,0,0,114, - 139,0,0,0,114,140,0,0,0,218,23,115,112,101,99,95, - 102,114,111,109,95,102,105,108,101,95,108,111,99,97,116,105, - 111,110,114,128,0,0,0,114,87,0,0,0,114,125,0,0, - 0,41,6,114,20,0,0,0,114,122,0,0,0,114,126,0, - 0,0,114,128,0,0,0,114,149,0,0,0,90,6,115,101, - 97,114,99,104,114,5,0,0,0,114,5,0,0,0,114,6, - 0,0,0,114,104,0,0,0,165,1,0,0,115,38,0,0, - 0,10,2,8,1,4,1,6,1,8,2,12,1,12,1,6, - 1,2,1,6,255,8,3,10,1,2,1,14,1,12,1,8, - 1,2,255,4,4,16,2,114,104,0,0,0,99,3,0,0, - 0,0,0,0,0,0,0,0,0,8,0,0,0,8,0,0, - 0,67,0,0,0,115,38,1,0,0,122,5,124,0,106,0, - 125,3,87,0,110,9,4,0,116,1,121,14,1,0,1,0, - 1,0,89,0,110,7,119,0,124,3,100,0,117,1,114,21, - 124,3,83,0,124,0,106,2,125,4,124,1,100,0,117,0, - 114,43,122,5,124,0,106,3,125,1,87,0,110,9,4,0, - 116,1,121,42,1,0,1,0,1,0,89,0,110,1,119,0, - 122,5,124,0,106,4,125,5,87,0,110,11,4,0,116,1, - 121,59,1,0,1,0,1,0,100,0,125,5,89,0,110,1, - 119,0,124,2,100,0,117,0,114,87,124,5,100,0,117,0, - 114,85,122,5,124,1,106,5,125,2,87,0,110,13,4,0, - 116,1,121,84,1,0,1,0,1,0,100,0,125,2,89,0, - 110,3,119,0,124,5,125,2,122,5,124,0,106,6,125,6, - 87,0,110,11,4,0,116,1,121,103,1,0,1,0,1,0, - 100,0,125,6,89,0,110,1,119,0,122,7,116,7,124,0, - 106,8,131,1,125,7,87,0,110,11,4,0,116,1,121,122, - 1,0,1,0,1,0,100,0,125,7,89,0,110,1,119,0, - 116,9,124,4,124,1,124,2,100,1,141,3,125,3,124,5, - 100,0,117,0,114,136,100,2,110,1,100,3,124,3,95,10, - 124,6,124,3,95,11,124,7,124,3,95,12,124,3,83,0, - 41,4,78,169,1,114,126,0,0,0,70,84,41,13,114,113, - 0,0,0,114,2,0,0,0,114,9,0,0,0,114,112,0, - 0,0,114,121,0,0,0,218,7,95,79,82,73,71,73,78, - 218,10,95,95,99,97,99,104,101,100,95,95,218,4,108,105, - 115,116,218,8,95,95,112,97,116,104,95,95,114,125,0,0, - 0,114,130,0,0,0,114,135,0,0,0,114,129,0,0,0, - 41,8,114,110,0,0,0,114,122,0,0,0,114,126,0,0, - 0,114,109,0,0,0,114,20,0,0,0,90,8,108,111,99, - 97,116,105,111,110,114,135,0,0,0,114,129,0,0,0,114, - 5,0,0,0,114,5,0,0,0,114,6,0,0,0,218,17, - 95,115,112,101,99,95,102,114,111,109,95,109,111,100,117,108, - 101,191,1,0,0,115,84,0,0,0,2,2,10,1,12,1, - 4,1,2,255,8,3,4,1,6,2,8,1,2,1,10,1, - 12,1,4,2,2,254,2,3,10,1,12,1,8,1,2,255, - 8,2,8,1,2,1,10,1,12,1,8,1,2,255,4,3, - 2,1,10,1,12,1,8,1,2,255,2,2,14,1,12,1, - 8,1,2,255,14,3,18,1,6,1,6,1,4,1,114,155, - 0,0,0,70,169,1,218,8,111,118,101,114,114,105,100,101, - 99,2,0,0,0,0,0,0,0,1,0,0,0,5,0,0, - 0,8,0,0,0,67,0,0,0,115,190,1,0,0,124,2, - 115,10,116,0,124,1,100,1,100,0,131,3,100,0,117,0, - 114,26,122,6,124,0,106,1,124,1,95,2,87,0,110,9, - 4,0,116,3,121,25,1,0,1,0,1,0,89,0,110,1, - 119,0,124,2,115,36,116,0,124,1,100,2,100,0,131,3, - 100,0,117,0,114,87,124,0,106,4,125,3,124,3,100,0, - 117,0,114,72,124,0,106,5,100,0,117,1,114,72,116,6, - 100,0,117,0,114,54,116,7,130,1,116,6,106,8,125,4, - 124,4,160,9,124,4,161,1,125,3,124,0,106,5,124,3, - 95,10,124,3,124,0,95,4,100,0,124,1,95,11,122,5, - 124,3,124,1,95,12,87,0,110,9,4,0,116,3,121,86, - 1,0,1,0,1,0,89,0,110,1,119,0,124,2,115,97, - 116,0,124,1,100,3,100,0,131,3,100,0,117,0,114,113, - 122,6,124,0,106,13,124,1,95,14,87,0,110,9,4,0, - 116,3,121,112,1,0,1,0,1,0,89,0,110,1,119,0, - 122,5,124,0,124,1,95,15,87,0,110,9,4,0,116,3, - 121,127,1,0,1,0,1,0,89,0,110,1,119,0,124,2, - 115,138,116,0,124,1,100,4,100,0,131,3,100,0,117,0, - 114,159,124,0,106,5,100,0,117,1,114,159,122,6,124,0, - 106,5,124,1,95,16,87,0,110,9,4,0,116,3,121,158, - 1,0,1,0,1,0,89,0,110,1,119,0,124,0,106,17, - 114,221,124,2,115,172,116,0,124,1,100,5,100,0,131,3, - 100,0,117,0,114,188,122,6,124,0,106,18,124,1,95,11, - 87,0,110,9,4,0,116,3,121,187,1,0,1,0,1,0, - 89,0,110,1,119,0,124,2,115,198,116,0,124,1,100,6, - 100,0,131,3,100,0,117,0,114,221,124,0,106,19,100,0, - 117,1,114,221,122,7,124,0,106,19,124,1,95,20,87,0, - 124,1,83,0,4,0,116,3,121,220,1,0,1,0,1,0, - 89,0,124,1,83,0,119,0,124,1,83,0,41,7,78,114, - 9,0,0,0,114,112,0,0,0,218,11,95,95,112,97,99, - 107,97,103,101,95,95,114,154,0,0,0,114,121,0,0,0, - 114,152,0,0,0,41,21,114,13,0,0,0,114,20,0,0, - 0,114,9,0,0,0,114,2,0,0,0,114,122,0,0,0, - 114,129,0,0,0,114,139,0,0,0,114,140,0,0,0,218, - 16,95,78,97,109,101,115,112,97,99,101,76,111,97,100,101, - 114,218,7,95,95,110,101,119,95,95,90,5,95,112,97,116, - 104,114,121,0,0,0,114,112,0,0,0,114,143,0,0,0, - 114,158,0,0,0,114,113,0,0,0,114,154,0,0,0,114, - 136,0,0,0,114,126,0,0,0,114,135,0,0,0,114,152, - 0,0,0,41,5,114,109,0,0,0,114,110,0,0,0,114, - 157,0,0,0,114,122,0,0,0,114,159,0,0,0,114,5, - 0,0,0,114,5,0,0,0,114,6,0,0,0,218,18,95, - 105,110,105,116,95,109,111,100,117,108,101,95,97,116,116,114, - 115,236,1,0,0,115,114,0,0,0,20,4,2,1,12,1, - 12,1,4,1,2,255,20,3,6,1,8,1,10,2,8,1, - 4,1,6,1,10,2,8,1,6,1,6,11,2,1,10,1, - 12,1,4,1,2,255,20,3,2,1,12,1,12,1,4,1, - 2,255,2,3,10,1,12,1,4,1,2,255,20,3,10,1, - 2,1,12,1,12,1,4,1,2,255,6,3,20,1,2,1, - 12,1,12,1,4,1,2,255,20,3,10,1,2,1,10,1, - 4,3,12,254,2,1,4,1,2,254,4,2,114,161,0,0, - 0,99,1,0,0,0,0,0,0,0,0,0,0,0,2,0, - 0,0,3,0,0,0,67,0,0,0,115,82,0,0,0,100, - 1,125,1,116,0,124,0,106,1,100,2,131,2,114,15,124, - 0,106,1,160,2,124,0,161,1,125,1,110,10,116,0,124, - 0,106,1,100,3,131,2,114,25,116,3,100,4,131,1,130, - 1,124,1,100,1,117,0,114,34,116,4,124,0,106,5,131, - 1,125,1,116,6,124,0,124,1,131,2,1,0,124,1,83, - 0,41,5,122,43,67,114,101,97,116,101,32,97,32,109,111, - 100,117,108,101,32,98,97,115,101,100,32,111,110,32,116,104, - 101,32,112,114,111,118,105,100,101,100,32,115,112,101,99,46, - 78,218,13,99,114,101,97,116,101,95,109,111,100,117,108,101, - 218,11,101,120,101,99,95,109,111,100,117,108,101,122,66,108, - 111,97,100,101,114,115,32,116,104,97,116,32,100,101,102,105, - 110,101,32,101,120,101,99,95,109,111,100,117,108,101,40,41, - 32,109,117,115,116,32,97,108,115,111,32,100,101,102,105,110, - 101,32,99,114,101,97,116,101,95,109,111,100,117,108,101,40, - 41,41,7,114,11,0,0,0,114,122,0,0,0,114,162,0, - 0,0,114,87,0,0,0,114,21,0,0,0,114,20,0,0, - 0,114,161,0,0,0,169,2,114,109,0,0,0,114,110,0, - 0,0,114,5,0,0,0,114,5,0,0,0,114,6,0,0, - 0,218,16,109,111,100,117,108,101,95,102,114,111,109,95,115, - 112,101,99,52,2,0,0,115,18,0,0,0,4,3,12,1, - 14,3,12,1,8,1,8,2,10,1,10,1,4,1,114,165, - 0,0,0,99,1,0,0,0,0,0,0,0,0,0,0,0, - 2,0,0,0,4,0,0,0,67,0,0,0,115,100,0,0, - 0,124,0,106,0,100,1,117,0,114,7,100,2,110,2,124, - 0,106,0,125,1,124,0,106,1,100,1,117,0,114,32,124, - 0,106,2,100,1,117,0,114,25,100,3,160,3,124,1,161, - 1,83,0,100,4,160,3,124,1,124,0,106,2,161,2,83, - 0,124,0,106,4,114,42,100,5,160,3,124,1,124,0,106, - 1,161,2,83,0,100,6,160,3,124,0,106,0,124,0,106, - 1,161,2,83,0,41,7,122,38,82,101,116,117,114,110,32, - 116,104,101,32,114,101,112,114,32,116,111,32,117,115,101,32, - 102,111,114,32,116,104,101,32,109,111,100,117,108,101,46,78, - 114,115,0,0,0,114,116,0,0,0,114,117,0,0,0,114, - 118,0,0,0,250,18,60,109,111,100,117,108,101,32,123,33, - 114,125,32,40,123,125,41,62,41,5,114,20,0,0,0,114, - 126,0,0,0,114,122,0,0,0,114,50,0,0,0,114,136, - 0,0,0,41,2,114,109,0,0,0,114,20,0,0,0,114, - 5,0,0,0,114,5,0,0,0,114,6,0,0,0,114,119, - 0,0,0,69,2,0,0,115,16,0,0,0,20,3,10,1, - 10,1,10,1,14,2,6,2,14,1,16,2,114,119,0,0, - 0,99,2,0,0,0,0,0,0,0,0,0,0,0,4,0, - 0,0,10,0,0,0,67,0,0,0,115,24,1,0,0,124, - 0,106,0,125,2,116,1,124,2,131,1,143,123,1,0,116, - 2,106,3,160,4,124,2,161,1,124,1,117,1,114,27,100, - 1,160,5,124,2,161,1,125,3,116,6,124,3,124,2,100, - 2,141,2,130,1,122,80,124,0,106,7,100,3,117,0,114, - 53,124,0,106,8,100,3,117,0,114,45,116,6,100,4,124, - 0,106,0,100,2,141,2,130,1,116,9,124,0,124,1,100, - 5,100,6,141,3,1,0,110,40,116,9,124,0,124,1,100, - 5,100,6,141,3,1,0,116,10,124,0,106,7,100,7,131, - 2,115,87,116,11,124,0,106,7,131,1,155,0,100,8,157, - 2,125,3,116,12,160,13,124,3,116,14,161,2,1,0,124, - 0,106,7,160,15,124,2,161,1,1,0,110,6,124,0,106, - 7,160,16,124,1,161,1,1,0,87,0,116,2,106,3,160, - 17,124,0,106,0,161,1,125,1,124,1,116,2,106,3,124, - 0,106,0,60,0,110,14,116,2,106,3,160,17,124,0,106, - 0,161,1,125,1,124,1,116,2,106,3,124,0,106,0,60, - 0,119,0,87,0,100,3,4,0,4,0,131,3,1,0,124, - 1,83,0,49,0,115,133,119,1,1,0,1,0,1,0,89, - 0,1,0,124,1,83,0,41,9,122,70,69,120,101,99,117, - 116,101,32,116,104,101,32,115,112,101,99,39,115,32,115,112, - 101,99,105,102,105,101,100,32,109,111,100,117,108,101,32,105, - 110,32,97,110,32,101,120,105,115,116,105,110,103,32,109,111, - 100,117,108,101,39,115,32,110,97,109,101,115,112,97,99,101, - 46,122,30,109,111,100,117,108,101,32,123,33,114,125,32,110, - 111,116,32,105,110,32,115,121,115,46,109,111,100,117,108,101, - 115,114,19,0,0,0,78,250,14,109,105,115,115,105,110,103, - 32,108,111,97,100,101,114,84,114,156,0,0,0,114,163,0, - 0,0,250,55,46,101,120,101,99,95,109,111,100,117,108,101, - 40,41,32,110,111,116,32,102,111,117,110,100,59,32,102,97, - 108,108,105,110,103,32,98,97,99,107,32,116,111,32,108,111, - 97,100,95,109,111,100,117,108,101,40,41,41,18,114,20,0, - 0,0,114,57,0,0,0,114,18,0,0,0,114,105,0,0, - 0,114,38,0,0,0,114,50,0,0,0,114,87,0,0,0, - 114,122,0,0,0,114,129,0,0,0,114,161,0,0,0,114, - 11,0,0,0,114,7,0,0,0,114,101,0,0,0,114,102, - 0,0,0,218,13,73,109,112,111,114,116,87,97,114,110,105, - 110,103,218,11,108,111,97,100,95,109,111,100,117,108,101,114, - 163,0,0,0,218,3,112,111,112,41,4,114,109,0,0,0, - 114,110,0,0,0,114,20,0,0,0,114,108,0,0,0,114, - 5,0,0,0,114,5,0,0,0,114,6,0,0,0,114,106, - 0,0,0,86,2,0,0,115,50,0,0,0,6,2,10,1, - 16,1,10,1,12,1,2,1,10,1,10,1,14,1,16,2, - 14,2,12,1,16,1,12,2,14,1,12,2,2,128,14,4, - 14,1,14,255,16,1,10,233,4,24,16,232,4,24,114,106, - 0,0,0,99,1,0,0,0,0,0,0,0,0,0,0,0, - 2,0,0,0,8,0,0,0,67,0,0,0,115,14,1,0, - 0,122,9,124,0,106,0,160,1,124,0,106,2,161,1,1, - 0,87,0,110,23,1,0,1,0,1,0,124,0,106,2,116, - 3,106,4,118,0,114,32,116,3,106,4,160,5,124,0,106, - 2,161,1,125,1,124,1,116,3,106,4,124,0,106,2,60, - 0,130,0,116,3,106,4,160,5,124,0,106,2,161,1,125, - 1,124,1,116,3,106,4,124,0,106,2,60,0,116,6,124, - 1,100,1,100,0,131,3,100,0,117,0,114,70,122,6,124, - 0,106,0,124,1,95,7,87,0,110,9,4,0,116,8,121, - 69,1,0,1,0,1,0,89,0,110,1,119,0,116,6,124, - 1,100,2,100,0,131,3,100,0,117,0,114,108,122,20,124, - 1,106,9,124,1,95,10,116,11,124,1,100,3,131,2,115, - 97,124,0,106,2,160,12,100,4,161,1,100,5,25,0,124, - 1,95,10,87,0,110,9,4,0,116,8,121,107,1,0,1, - 0,1,0,89,0,110,1,119,0,116,6,124,1,100,6,100, - 0,131,3,100,0,117,0,114,133,122,6,124,0,124,1,95, - 13,87,0,124,1,83,0,4,0,116,8,121,132,1,0,1, - 0,1,0,89,0,124,1,83,0,119,0,124,1,83,0,41, - 7,78,114,112,0,0,0,114,158,0,0,0,114,154,0,0, - 0,114,141,0,0,0,114,25,0,0,0,114,113,0,0,0, - 41,14,114,122,0,0,0,114,170,0,0,0,114,20,0,0, - 0,114,18,0,0,0,114,105,0,0,0,114,171,0,0,0, - 114,13,0,0,0,114,112,0,0,0,114,2,0,0,0,114, - 9,0,0,0,114,158,0,0,0,114,11,0,0,0,114,142, - 0,0,0,114,113,0,0,0,114,164,0,0,0,114,5,0, - 0,0,114,5,0,0,0,114,6,0,0,0,218,25,95,108, - 111,97,100,95,98,97,99,107,119,97,114,100,95,99,111,109, - 112,97,116,105,98,108,101,116,2,0,0,115,66,0,0,0, - 2,3,18,1,6,1,12,1,14,1,12,1,2,1,14,3, - 12,1,16,1,2,1,12,1,12,1,4,1,2,255,16,2, - 2,1,8,4,10,1,18,1,4,128,12,1,4,1,2,255, - 16,2,2,1,8,1,4,3,12,254,2,1,4,1,2,254, - 4,2,114,172,0,0,0,99,1,0,0,0,0,0,0,0, - 0,0,0,0,3,0,0,0,11,0,0,0,67,0,0,0, - 115,242,0,0,0,124,0,106,0,100,0,117,1,114,29,116, - 1,124,0,106,0,100,1,131,2,115,29,116,2,124,0,106, - 0,131,1,155,0,100,2,157,2,125,1,116,3,160,4,124, - 1,116,5,161,2,1,0,116,6,124,0,131,1,83,0,116, - 7,124,0,131,1,125,2,100,3,124,0,95,8,122,80,124, - 2,116,9,106,10,124,0,106,11,60,0,122,26,124,0,106, - 0,100,0,117,0,114,62,124,0,106,12,100,0,117,0,114, - 61,116,13,100,4,124,0,106,11,100,5,141,2,130,1,110, - 6,124,0,106,0,160,14,124,2,161,1,1,0,87,0,110, - 20,1,0,1,0,1,0,122,7,116,9,106,10,124,0,106, - 11,61,0,87,0,130,0,4,0,116,15,121,89,1,0,1, - 0,1,0,89,0,130,0,119,0,116,9,106,10,160,16,124, - 0,106,11,161,1,125,2,124,2,116,9,106,10,124,0,106, - 11,60,0,116,17,100,6,124,0,106,11,124,0,106,0,131, - 3,1,0,87,0,100,7,124,0,95,8,124,2,83,0,100, - 7,124,0,95,8,119,0,41,8,78,114,163,0,0,0,114, - 168,0,0,0,84,114,167,0,0,0,114,19,0,0,0,122, - 18,105,109,112,111,114,116,32,123,33,114,125,32,35,32,123, - 33,114,125,70,41,18,114,122,0,0,0,114,11,0,0,0, - 114,7,0,0,0,114,101,0,0,0,114,102,0,0,0,114, - 169,0,0,0,114,172,0,0,0,114,165,0,0,0,90,13, - 95,105,110,105,116,105,97,108,105,122,105,110,103,114,18,0, - 0,0,114,105,0,0,0,114,20,0,0,0,114,129,0,0, - 0,114,87,0,0,0,114,163,0,0,0,114,70,0,0,0, - 114,171,0,0,0,114,83,0,0,0,41,3,114,109,0,0, - 0,114,108,0,0,0,114,110,0,0,0,114,5,0,0,0, - 114,5,0,0,0,114,6,0,0,0,218,14,95,108,111,97, - 100,95,117,110,108,111,99,107,101,100,152,2,0,0,115,60, - 0,0,0,10,2,12,2,16,1,12,2,8,1,8,2,6, - 5,2,1,12,1,2,1,10,1,10,1,14,1,2,255,12, - 4,4,128,6,1,2,1,12,1,2,3,12,254,2,1,2, - 1,2,254,14,7,12,1,18,1,6,2,4,2,8,254,114, - 173,0,0,0,99,1,0,0,0,0,0,0,0,0,0,0, - 0,1,0,0,0,8,0,0,0,67,0,0,0,115,54,0, - 0,0,116,0,124,0,106,1,131,1,143,12,1,0,116,2, - 124,0,131,1,87,0,2,0,100,1,4,0,4,0,131,3, - 1,0,83,0,49,0,115,20,119,1,1,0,1,0,1,0, - 89,0,1,0,100,1,83,0,41,2,122,191,82,101,116,117, - 114,110,32,97,32,110,101,119,32,109,111,100,117,108,101,32, - 111,98,106,101,99,116,44,32,108,111,97,100,101,100,32,98, - 121,32,116,104,101,32,115,112,101,99,39,115,32,108,111,97, - 100,101,114,46,10,10,32,32,32,32,84,104,101,32,109,111, - 100,117,108,101,32,105,115,32,110,111,116,32,97,100,100,101, - 100,32,116,111,32,105,116,115,32,112,97,114,101,110,116,46, - 10,10,32,32,32,32,73,102,32,97,32,109,111,100,117,108, - 101,32,105,115,32,97,108,114,101,97,100,121,32,105,110,32, - 115,121,115,46,109,111,100,117,108,101,115,44,32,116,104,97, - 116,32,101,120,105,115,116,105,110,103,32,109,111,100,117,108, - 101,32,103,101,116,115,10,32,32,32,32,99,108,111,98,98, - 101,114,101,100,46,10,10,32,32,32,32,78,41,3,114,57, - 0,0,0,114,20,0,0,0,114,173,0,0,0,169,1,114, - 109,0,0,0,114,5,0,0,0,114,5,0,0,0,114,6, - 0,0,0,114,107,0,0,0,197,2,0,0,115,6,0,0, - 0,12,9,6,1,36,255,114,107,0,0,0,99,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0, - 0,64,0,0,0,115,140,0,0,0,101,0,90,1,100,0, - 90,2,100,1,90,3,100,2,90,4,101,5,100,3,100,4, - 132,0,131,1,90,6,101,7,100,20,100,6,100,7,132,1, - 131,1,90,8,101,7,100,21,100,8,100,9,132,1,131,1, - 90,9,101,5,100,10,100,11,132,0,131,1,90,10,101,5, - 100,12,100,13,132,0,131,1,90,11,101,7,101,12,100,14, - 100,15,132,0,131,1,131,1,90,13,101,7,101,12,100,16, - 100,17,132,0,131,1,131,1,90,14,101,7,101,12,100,18, - 100,19,132,0,131,1,131,1,90,15,101,7,101,16,131,1, - 90,17,100,5,83,0,41,22,218,15,66,117,105,108,116,105, - 110,73,109,112,111,114,116,101,114,122,144,77,101,116,97,32, - 112,97,116,104,32,105,109,112,111,114,116,32,102,111,114,32, - 98,117,105,108,116,45,105,110,32,109,111,100,117,108,101,115, - 46,10,10,32,32,32,32,65,108,108,32,109,101,116,104,111, - 100,115,32,97,114,101,32,101,105,116,104,101,114,32,99,108, - 97,115,115,32,111,114,32,115,116,97,116,105,99,32,109,101, - 116,104,111,100,115,32,116,111,32,97,118,111,105,100,32,116, - 104,101,32,110,101,101,100,32,116,111,10,32,32,32,32,105, - 110,115,116,97,110,116,105,97,116,101,32,116,104,101,32,99, - 108,97,115,115,46,10,10,32,32,32,32,122,8,98,117,105, - 108,116,45,105,110,99,1,0,0,0,0,0,0,0,0,0, - 0,0,1,0,0,0,5,0,0,0,67,0,0,0,115,34, - 0,0,0,116,0,160,1,100,1,116,2,161,2,1,0,100, - 2,124,0,106,3,155,2,100,3,116,4,106,5,155,0,100, - 4,157,5,83,0,41,5,250,115,82,101,116,117,114,110,32, - 114,101,112,114,32,102,111,114,32,116,104,101,32,109,111,100, - 117,108,101,46,10,10,32,32,32,32,32,32,32,32,84,104, - 101,32,109,101,116,104,111,100,32,105,115,32,100,101,112,114, - 101,99,97,116,101,100,46,32,32,84,104,101,32,105,109,112, - 111,114,116,32,109,97,99,104,105,110,101,114,121,32,100,111, - 101,115,32,116,104,101,32,106,111,98,32,105,116,115,101,108, - 102,46,10,10,32,32,32,32,32,32,32,32,122,81,66,117, - 105,108,116,105,110,73,109,112,111,114,116,101,114,46,109,111, - 100,117,108,101,95,114,101,112,114,40,41,32,105,115,32,100, - 101,112,114,101,99,97,116,101,100,32,97,110,100,32,115,108, - 97,116,101,100,32,102,111,114,32,114,101,109,111,118,97,108, - 32,105,110,32,80,121,116,104,111,110,32,51,46,49,50,122, - 8,60,109,111,100,117,108,101,32,122,2,32,40,122,2,41, - 62,41,6,114,101,0,0,0,114,102,0,0,0,114,103,0, - 0,0,114,9,0,0,0,114,175,0,0,0,114,151,0,0, - 0,169,1,114,110,0,0,0,114,5,0,0,0,114,5,0, - 0,0,114,6,0,0,0,114,114,0,0,0,223,2,0,0, - 115,8,0,0,0,6,7,2,1,4,255,22,2,122,27,66, - 117,105,108,116,105,110,73,109,112,111,114,116,101,114,46,109, - 111,100,117,108,101,95,114,101,112,114,78,99,4,0,0,0, - 0,0,0,0,0,0,0,0,4,0,0,0,5,0,0,0, - 67,0,0,0,115,42,0,0,0,124,2,100,0,117,1,114, - 6,100,0,83,0,116,0,160,1,124,1,161,1,114,19,116, - 2,124,1,124,0,124,0,106,3,100,1,141,3,83,0,100, - 0,83,0,169,2,78,114,150,0,0,0,41,4,114,64,0, - 0,0,90,10,105,115,95,98,117,105,108,116,105,110,114,104, - 0,0,0,114,151,0,0,0,169,4,218,3,99,108,115,114, - 89,0,0,0,218,4,112,97,116,104,218,6,116,97,114,103, - 101,116,114,5,0,0,0,114,5,0,0,0,114,6,0,0, - 0,218,9,102,105,110,100,95,115,112,101,99,234,2,0,0, - 115,10,0,0,0,8,2,4,1,10,1,16,1,4,2,122, - 25,66,117,105,108,116,105,110,73,109,112,111,114,116,101,114, - 46,102,105,110,100,95,115,112,101,99,99,3,0,0,0,0, - 0,0,0,0,0,0,0,4,0,0,0,4,0,0,0,67, - 0,0,0,115,42,0,0,0,116,0,160,1,100,1,116,2, - 161,2,1,0,124,0,160,3,124,1,124,2,161,2,125,3, - 124,3,100,2,117,1,114,19,124,3,106,4,83,0,100,2, - 83,0,41,3,122,175,70,105,110,100,32,116,104,101,32,98, - 117,105,108,116,45,105,110,32,109,111,100,117,108,101,46,10, - 10,32,32,32,32,32,32,32,32,73,102,32,39,112,97,116, - 104,39,32,105,115,32,101,118,101,114,32,115,112,101,99,105, - 102,105,101,100,32,116,104,101,110,32,116,104,101,32,115,101, - 97,114,99,104,32,105,115,32,99,111,110,115,105,100,101,114, - 101,100,32,97,32,102,97,105,108,117,114,101,46,10,10,32, - 32,32,32,32,32,32,32,84,104,105,115,32,109,101,116,104, - 111,100,32,105,115,32,100,101,112,114,101,99,97,116,101,100, - 46,32,32,85,115,101,32,102,105,110,100,95,115,112,101,99, - 40,41,32,105,110,115,116,101,97,100,46,10,10,32,32,32, - 32,32,32,32,32,122,106,66,117,105,108,116,105,110,73,109, - 112,111,114,116,101,114,46,102,105,110,100,95,109,111,100,117, - 108,101,40,41,32,105,115,32,100,101,112,114,101,99,97,116, - 101,100,32,97,110,100,32,115,108,97,116,101,100,32,102,111, - 114,32,114,101,109,111,118,97,108,32,105,110,32,80,121,116, - 104,111,110,32,51,46,49,50,59,32,117,115,101,32,102,105, - 110,100,95,115,112,101,99,40,41,32,105,110,115,116,101,97, - 100,78,41,5,114,101,0,0,0,114,102,0,0,0,114,103, - 0,0,0,114,183,0,0,0,114,122,0,0,0,41,4,114, - 180,0,0,0,114,89,0,0,0,114,181,0,0,0,114,109, - 0,0,0,114,5,0,0,0,114,5,0,0,0,114,6,0, - 0,0,218,11,102,105,110,100,95,109,111,100,117,108,101,243, - 2,0,0,115,10,0,0,0,6,9,2,2,4,254,12,3, - 18,1,122,27,66,117,105,108,116,105,110,73,109,112,111,114, - 116,101,114,46,102,105,110,100,95,109,111,100,117,108,101,99, - 1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0, - 4,0,0,0,67,0,0,0,115,46,0,0,0,124,0,106, - 0,116,1,106,2,118,1,114,17,116,3,100,1,160,4,124, - 0,106,0,161,1,124,0,106,0,100,2,141,2,130,1,116, - 5,116,6,106,7,124,0,131,2,83,0,41,3,122,24,67, - 114,101,97,116,101,32,97,32,98,117,105,108,116,45,105,110, - 32,109,111,100,117,108,101,114,85,0,0,0,114,19,0,0, - 0,41,8,114,20,0,0,0,114,18,0,0,0,114,86,0, - 0,0,114,87,0,0,0,114,50,0,0,0,114,74,0,0, - 0,114,64,0,0,0,90,14,99,114,101,97,116,101,95,98, - 117,105,108,116,105,110,114,174,0,0,0,114,5,0,0,0, - 114,5,0,0,0,114,6,0,0,0,114,162,0,0,0,2, - 3,0,0,115,10,0,0,0,12,3,12,1,4,1,6,255, - 12,2,122,29,66,117,105,108,116,105,110,73,109,112,111,114, - 116,101,114,46,99,114,101,97,116,101,95,109,111,100,117,108, - 101,99,1,0,0,0,0,0,0,0,0,0,0,0,1,0, - 0,0,3,0,0,0,67,0,0,0,115,16,0,0,0,116, - 0,116,1,106,2,124,0,131,2,1,0,100,1,83,0,41, - 2,122,22,69,120,101,99,32,97,32,98,117,105,108,116,45, - 105,110,32,109,111,100,117,108,101,78,41,3,114,74,0,0, - 0,114,64,0,0,0,90,12,101,120,101,99,95,98,117,105, - 108,116,105,110,114,177,0,0,0,114,5,0,0,0,114,5, - 0,0,0,114,6,0,0,0,114,163,0,0,0,10,3,0, - 0,115,2,0,0,0,16,3,122,27,66,117,105,108,116,105, - 110,73,109,112,111,114,116,101,114,46,101,120,101,99,95,109, - 111,100,117,108,101,99,2,0,0,0,0,0,0,0,0,0, - 0,0,2,0,0,0,1,0,0,0,67,0,0,0,243,4, - 0,0,0,100,1,83,0,41,2,122,57,82,101,116,117,114, - 110,32,78,111,110,101,32,97,115,32,98,117,105,108,116,45, - 105,110,32,109,111,100,117,108,101,115,32,100,111,32,110,111, - 116,32,104,97,118,101,32,99,111,100,101,32,111,98,106,101, - 99,116,115,46,78,114,5,0,0,0,169,2,114,180,0,0, - 0,114,89,0,0,0,114,5,0,0,0,114,5,0,0,0, - 114,6,0,0,0,218,8,103,101,116,95,99,111,100,101,15, - 3,0,0,243,2,0,0,0,4,4,122,24,66,117,105,108, - 116,105,110,73,109,112,111,114,116,101,114,46,103,101,116,95, - 99,111,100,101,99,2,0,0,0,0,0,0,0,0,0,0, - 0,2,0,0,0,1,0,0,0,67,0,0,0,114,185,0, - 0,0,41,2,122,56,82,101,116,117,114,110,32,78,111,110, - 101,32,97,115,32,98,117,105,108,116,45,105,110,32,109,111, - 100,117,108,101,115,32,100,111,32,110,111,116,32,104,97,118, - 101,32,115,111,117,114,99,101,32,99,111,100,101,46,78,114, - 5,0,0,0,114,186,0,0,0,114,5,0,0,0,114,5, - 0,0,0,114,6,0,0,0,218,10,103,101,116,95,115,111, - 117,114,99,101,21,3,0,0,114,188,0,0,0,122,26,66, - 117,105,108,116,105,110,73,109,112,111,114,116,101,114,46,103, - 101,116,95,115,111,117,114,99,101,99,2,0,0,0,0,0, - 0,0,0,0,0,0,2,0,0,0,1,0,0,0,67,0, - 0,0,114,185,0,0,0,41,2,122,52,82,101,116,117,114, - 110,32,70,97,108,115,101,32,97,115,32,98,117,105,108,116, - 45,105,110,32,109,111,100,117,108,101,115,32,97,114,101,32, - 110,101,118,101,114,32,112,97,99,107,97,103,101,115,46,70, - 114,5,0,0,0,114,186,0,0,0,114,5,0,0,0,114, - 5,0,0,0,114,6,0,0,0,114,128,0,0,0,27,3, - 0,0,114,188,0,0,0,122,26,66,117,105,108,116,105,110, - 73,109,112,111,114,116,101,114,46,105,115,95,112,97,99,107, - 97,103,101,169,2,78,78,114,0,0,0,0,41,18,114,9, - 0,0,0,114,8,0,0,0,114,1,0,0,0,114,10,0, - 0,0,114,151,0,0,0,218,12,115,116,97,116,105,99,109, - 101,116,104,111,100,114,114,0,0,0,218,11,99,108,97,115, - 115,109,101,116,104,111,100,114,183,0,0,0,114,184,0,0, - 0,114,162,0,0,0,114,163,0,0,0,114,95,0,0,0, - 114,187,0,0,0,114,189,0,0,0,114,128,0,0,0,114, - 111,0,0,0,114,170,0,0,0,114,5,0,0,0,114,5, - 0,0,0,114,5,0,0,0,114,6,0,0,0,114,175,0, - 0,0,212,2,0,0,115,46,0,0,0,8,0,4,2,4, - 7,2,2,10,1,2,10,12,1,2,8,12,1,2,14,10, - 1,2,7,10,1,2,4,2,1,12,1,2,4,2,1,12, - 1,2,4,2,1,12,1,12,4,114,175,0,0,0,99,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4, - 0,0,0,64,0,0,0,115,144,0,0,0,101,0,90,1, - 100,0,90,2,100,1,90,3,100,2,90,4,101,5,100,3, - 100,4,132,0,131,1,90,6,101,7,100,22,100,6,100,7, - 132,1,131,1,90,8,101,7,100,23,100,8,100,9,132,1, - 131,1,90,9,101,5,100,10,100,11,132,0,131,1,90,10, - 101,5,100,12,100,13,132,0,131,1,90,11,101,7,100,14, - 100,15,132,0,131,1,90,12,101,7,101,13,100,16,100,17, - 132,0,131,1,131,1,90,14,101,7,101,13,100,18,100,19, - 132,0,131,1,131,1,90,15,101,7,101,13,100,20,100,21, - 132,0,131,1,131,1,90,16,100,5,83,0,41,24,218,14, - 70,114,111,122,101,110,73,109,112,111,114,116,101,114,122,142, - 77,101,116,97,32,112,97,116,104,32,105,109,112,111,114,116, - 32,102,111,114,32,102,114,111,122,101,110,32,109,111,100,117, - 108,101,115,46,10,10,32,32,32,32,65,108,108,32,109,101, - 116,104,111,100,115,32,97,114,101,32,101,105,116,104,101,114, - 32,99,108,97,115,115,32,111,114,32,115,116,97,116,105,99, - 32,109,101,116,104,111,100,115,32,116,111,32,97,118,111,105, - 100,32,116,104,101,32,110,101,101,100,32,116,111,10,32,32, - 32,32,105,110,115,116,97,110,116,105,97,116,101,32,116,104, - 101,32,99,108,97,115,115,46,10,10,32,32,32,32,90,6, - 102,114,111,122,101,110,99,1,0,0,0,0,0,0,0,0, - 0,0,0,1,0,0,0,4,0,0,0,67,0,0,0,115, - 28,0,0,0,116,0,160,1,100,1,116,2,161,2,1,0, - 100,2,160,3,124,0,106,4,116,5,106,6,161,2,83,0, - 41,3,114,176,0,0,0,122,80,70,114,111,122,101,110,73, - 109,112,111,114,116,101,114,46,109,111,100,117,108,101,95,114, - 101,112,114,40,41,32,105,115,32,100,101,112,114,101,99,97, - 116,101,100,32,97,110,100,32,115,108,97,116,101,100,32,102, - 111,114,32,114,101,109,111,118,97,108,32,105,110,32,80,121, - 116,104,111,110,32,51,46,49,50,114,166,0,0,0,41,7, - 114,101,0,0,0,114,102,0,0,0,114,103,0,0,0,114, - 50,0,0,0,114,9,0,0,0,114,193,0,0,0,114,151, - 0,0,0,41,1,218,1,109,114,5,0,0,0,114,5,0, - 0,0,114,6,0,0,0,114,114,0,0,0,47,3,0,0, - 115,8,0,0,0,6,7,2,1,4,255,16,2,122,26,70, - 114,111,122,101,110,73,109,112,111,114,116,101,114,46,109,111, - 100,117,108,101,95,114,101,112,114,78,99,4,0,0,0,0, - 0,0,0,0,0,0,0,4,0,0,0,5,0,0,0,67, - 0,0,0,115,30,0,0,0,116,0,160,1,124,1,161,1, - 114,13,116,2,124,1,124,0,124,0,106,3,100,1,141,3, - 83,0,100,0,83,0,114,178,0,0,0,41,4,114,64,0, - 0,0,114,98,0,0,0,114,104,0,0,0,114,151,0,0, - 0,114,179,0,0,0,114,5,0,0,0,114,5,0,0,0, - 114,6,0,0,0,114,183,0,0,0,58,3,0,0,115,6, - 0,0,0,10,2,16,1,4,2,122,24,70,114,111,122,101, - 110,73,109,112,111,114,116,101,114,46,102,105,110,100,95,115, - 112,101,99,99,3,0,0,0,0,0,0,0,0,0,0,0, - 3,0,0,0,4,0,0,0,67,0,0,0,115,30,0,0, - 0,116,0,160,1,100,1,116,2,161,2,1,0,116,3,160, - 4,124,1,161,1,114,13,124,0,83,0,100,2,83,0,41, - 3,122,93,70,105,110,100,32,97,32,102,114,111,122,101,110, - 32,109,111,100,117,108,101,46,10,10,32,32,32,32,32,32, - 32,32,84,104,105,115,32,109,101,116,104,111,100,32,105,115, - 32,100,101,112,114,101,99,97,116,101,100,46,32,32,85,115, - 101,32,102,105,110,100,95,115,112,101,99,40,41,32,105,110, - 115,116,101,97,100,46,10,10,32,32,32,32,32,32,32,32, - 122,105,70,114,111,122,101,110,73,109,112,111,114,116,101,114, - 46,102,105,110,100,95,109,111,100,117,108,101,40,41,32,105, - 115,32,100,101,112,114,101,99,97,116,101,100,32,97,110,100, - 32,115,108,97,116,101,100,32,102,111,114,32,114,101,109,111, - 118,97,108,32,105,110,32,80,121,116,104,111,110,32,51,46, - 49,50,59,32,117,115,101,32,102,105,110,100,95,115,112,101, - 99,40,41,32,105,110,115,116,101,97,100,78,41,5,114,101, - 0,0,0,114,102,0,0,0,114,103,0,0,0,114,64,0, - 0,0,114,98,0,0,0,41,3,114,180,0,0,0,114,89, - 0,0,0,114,181,0,0,0,114,5,0,0,0,114,5,0, - 0,0,114,6,0,0,0,114,184,0,0,0,65,3,0,0, - 115,8,0,0,0,6,7,2,2,4,254,18,3,122,26,70, - 114,111,122,101,110,73,109,112,111,114,116,101,114,46,102,105, - 110,100,95,109,111,100,117,108,101,99,1,0,0,0,0,0, - 0,0,0,0,0,0,1,0,0,0,1,0,0,0,67,0, - 0,0,114,185,0,0,0,41,2,122,42,85,115,101,32,100, - 101,102,97,117,108,116,32,115,101,109,97,110,116,105,99,115, - 32,102,111,114,32,109,111,100,117,108,101,32,99,114,101,97, - 116,105,111,110,46,78,114,5,0,0,0,114,174,0,0,0, - 114,5,0,0,0,114,5,0,0,0,114,6,0,0,0,114, - 162,0,0,0,77,3,0,0,115,2,0,0,0,4,0,122, - 28,70,114,111,122,101,110,73,109,112,111,114,116,101,114,46, - 99,114,101,97,116,101,95,109,111,100,117,108,101,99,1,0, - 0,0,0,0,0,0,0,0,0,0,3,0,0,0,4,0, - 0,0,67,0,0,0,115,64,0,0,0,124,0,106,0,106, - 1,125,1,116,2,160,3,124,1,161,1,115,18,116,4,100, - 1,160,5,124,1,161,1,124,1,100,2,141,2,130,1,116, - 6,116,2,106,7,124,1,131,2,125,2,116,8,124,2,124, - 0,106,9,131,2,1,0,100,0,83,0,114,97,0,0,0, - 41,10,114,113,0,0,0,114,20,0,0,0,114,64,0,0, - 0,114,98,0,0,0,114,87,0,0,0,114,50,0,0,0, - 114,74,0,0,0,218,17,103,101,116,95,102,114,111,122,101, - 110,95,111,98,106,101,99,116,218,4,101,120,101,99,114,14, - 0,0,0,41,3,114,110,0,0,0,114,20,0,0,0,218, - 4,99,111,100,101,114,5,0,0,0,114,5,0,0,0,114, - 6,0,0,0,114,163,0,0,0,81,3,0,0,115,14,0, - 0,0,8,2,10,1,10,1,2,1,6,255,12,2,16,1, - 122,26,70,114,111,122,101,110,73,109,112,111,114,116,101,114, - 46,101,120,101,99,95,109,111,100,117,108,101,99,2,0,0, - 0,0,0,0,0,0,0,0,0,2,0,0,0,3,0,0, - 0,67,0,0,0,115,10,0,0,0,116,0,124,0,124,1, - 131,2,83,0,41,1,122,95,76,111,97,100,32,97,32,102, - 114,111,122,101,110,32,109,111,100,117,108,101,46,10,10,32, - 32,32,32,32,32,32,32,84,104,105,115,32,109,101,116,104, - 111,100,32,105,115,32,100,101,112,114,101,99,97,116,101,100, - 46,32,32,85,115,101,32,101,120,101,99,95,109,111,100,117, - 108,101,40,41,32,105,110,115,116,101,97,100,46,10,10,32, - 32,32,32,32,32,32,32,41,1,114,111,0,0,0,114,186, - 0,0,0,114,5,0,0,0,114,5,0,0,0,114,6,0, - 0,0,114,170,0,0,0,90,3,0,0,115,2,0,0,0, - 10,8,122,26,70,114,111,122,101,110,73,109,112,111,114,116, - 101,114,46,108,111,97,100,95,109,111,100,117,108,101,99,2, - 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,3, - 0,0,0,67,0,0,0,243,10,0,0,0,116,0,160,1, - 124,1,161,1,83,0,41,1,122,45,82,101,116,117,114,110, - 32,116,104,101,32,99,111,100,101,32,111,98,106,101,99,116, - 32,102,111,114,32,116,104,101,32,102,114,111,122,101,110,32, - 109,111,100,117,108,101,46,41,2,114,64,0,0,0,114,195, - 0,0,0,114,186,0,0,0,114,5,0,0,0,114,5,0, - 0,0,114,6,0,0,0,114,187,0,0,0,100,3,0,0, - 243,2,0,0,0,10,4,122,23,70,114,111,122,101,110,73, - 109,112,111,114,116,101,114,46,103,101,116,95,99,111,100,101, - 99,2,0,0,0,0,0,0,0,0,0,0,0,2,0,0, - 0,1,0,0,0,67,0,0,0,114,185,0,0,0,41,2, - 122,54,82,101,116,117,114,110,32,78,111,110,101,32,97,115, - 32,102,114,111,122,101,110,32,109,111,100,117,108,101,115,32, - 100,111,32,110,111,116,32,104,97,118,101,32,115,111,117,114, - 99,101,32,99,111,100,101,46,78,114,5,0,0,0,114,186, - 0,0,0,114,5,0,0,0,114,5,0,0,0,114,6,0, - 0,0,114,189,0,0,0,106,3,0,0,114,188,0,0,0, - 122,25,70,114,111,122,101,110,73,109,112,111,114,116,101,114, - 46,103,101,116,95,115,111,117,114,99,101,99,2,0,0,0, - 0,0,0,0,0,0,0,0,2,0,0,0,3,0,0,0, - 67,0,0,0,114,198,0,0,0,41,1,122,46,82,101,116, - 117,114,110,32,84,114,117,101,32,105,102,32,116,104,101,32, - 102,114,111,122,101,110,32,109,111,100,117,108,101,32,105,115, - 32,97,32,112,97,99,107,97,103,101,46,41,2,114,64,0, - 0,0,90,17,105,115,95,102,114,111,122,101,110,95,112,97, - 99,107,97,103,101,114,186,0,0,0,114,5,0,0,0,114, - 5,0,0,0,114,6,0,0,0,114,128,0,0,0,112,3, - 0,0,114,199,0,0,0,122,25,70,114,111,122,101,110,73, - 109,112,111,114,116,101,114,46,105,115,95,112,97,99,107,97, - 103,101,114,190,0,0,0,114,0,0,0,0,41,17,114,9, - 0,0,0,114,8,0,0,0,114,1,0,0,0,114,10,0, - 0,0,114,151,0,0,0,114,191,0,0,0,114,114,0,0, - 0,114,192,0,0,0,114,183,0,0,0,114,184,0,0,0, - 114,162,0,0,0,114,163,0,0,0,114,170,0,0,0,114, - 100,0,0,0,114,187,0,0,0,114,189,0,0,0,114,128, - 0,0,0,114,5,0,0,0,114,5,0,0,0,114,5,0, - 0,0,114,6,0,0,0,114,193,0,0,0,36,3,0,0, - 115,48,0,0,0,8,0,4,2,4,7,2,2,10,1,2, - 10,12,1,2,6,12,1,2,11,10,1,2,3,10,1,2, - 8,10,1,2,9,2,1,12,1,2,4,2,1,12,1,2, - 4,2,1,16,1,114,193,0,0,0,99,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,64, - 0,0,0,115,32,0,0,0,101,0,90,1,100,0,90,2, - 100,1,90,3,100,2,100,3,132,0,90,4,100,4,100,5, - 132,0,90,5,100,6,83,0,41,7,218,18,95,73,109,112, - 111,114,116,76,111,99,107,67,111,110,116,101,120,116,122,36, - 67,111,110,116,101,120,116,32,109,97,110,97,103,101,114,32, - 102,111,114,32,116,104,101,32,105,109,112,111,114,116,32,108, - 111,99,107,46,99,1,0,0,0,0,0,0,0,0,0,0, - 0,1,0,0,0,2,0,0,0,67,0,0,0,243,12,0, - 0,0,116,0,160,1,161,0,1,0,100,1,83,0,41,2, - 122,24,65,99,113,117,105,114,101,32,116,104,101,32,105,109, - 112,111,114,116,32,108,111,99,107,46,78,41,2,114,64,0, - 0,0,114,65,0,0,0,114,52,0,0,0,114,5,0,0, - 0,114,5,0,0,0,114,6,0,0,0,114,61,0,0,0, - 125,3,0,0,243,2,0,0,0,12,2,122,28,95,73,109, - 112,111,114,116,76,111,99,107,67,111,110,116,101,120,116,46, - 95,95,101,110,116,101,114,95,95,99,4,0,0,0,0,0, - 0,0,0,0,0,0,4,0,0,0,2,0,0,0,67,0, - 0,0,114,201,0,0,0,41,2,122,60,82,101,108,101,97, - 115,101,32,116,104,101,32,105,109,112,111,114,116,32,108,111, - 99,107,32,114,101,103,97,114,100,108,101,115,115,32,111,102, - 32,97,110,121,32,114,97,105,115,101,100,32,101,120,99,101, - 112,116,105,111,110,115,46,78,41,2,114,64,0,0,0,114, - 67,0,0,0,41,4,114,33,0,0,0,218,8,101,120,99, - 95,116,121,112,101,218,9,101,120,99,95,118,97,108,117,101, - 218,13,101,120,99,95,116,114,97,99,101,98,97,99,107,114, - 5,0,0,0,114,5,0,0,0,114,6,0,0,0,114,63, - 0,0,0,129,3,0,0,114,202,0,0,0,122,27,95,73, - 109,112,111,114,116,76,111,99,107,67,111,110,116,101,120,116, - 46,95,95,101,120,105,116,95,95,78,41,6,114,9,0,0, - 0,114,8,0,0,0,114,1,0,0,0,114,10,0,0,0, - 114,61,0,0,0,114,63,0,0,0,114,5,0,0,0,114, - 5,0,0,0,114,5,0,0,0,114,6,0,0,0,114,200, - 0,0,0,121,3,0,0,115,8,0,0,0,8,0,4,2, - 8,2,12,4,114,200,0,0,0,99,3,0,0,0,0,0, - 0,0,0,0,0,0,5,0,0,0,5,0,0,0,67,0, - 0,0,115,64,0,0,0,124,1,160,0,100,1,124,2,100, - 2,24,0,161,2,125,3,116,1,124,3,131,1,124,2,107, - 0,114,18,116,2,100,3,131,1,130,1,124,3,100,4,25, - 0,125,4,124,0,114,30,100,5,160,3,124,4,124,0,161, - 2,83,0,124,4,83,0,41,6,122,50,82,101,115,111,108, - 118,101,32,97,32,114,101,108,97,116,105,118,101,32,109,111, - 100,117,108,101,32,110,97,109,101,32,116,111,32,97,110,32, - 97,98,115,111,108,117,116,101,32,111,110,101,46,114,141,0, - 0,0,114,42,0,0,0,122,50,97,116,116,101,109,112,116, - 101,100,32,114,101,108,97,116,105,118,101,32,105,109,112,111, - 114,116,32,98,101,121,111,110,100,32,116,111,112,45,108,101, - 118,101,108,32,112,97,99,107,97,103,101,114,25,0,0,0, - 250,5,123,125,46,123,125,41,4,218,6,114,115,112,108,105, - 116,218,3,108,101,110,114,87,0,0,0,114,50,0,0,0, - 41,5,114,20,0,0,0,218,7,112,97,99,107,97,103,101, - 218,5,108,101,118,101,108,90,4,98,105,116,115,90,4,98, - 97,115,101,114,5,0,0,0,114,5,0,0,0,114,6,0, - 0,0,218,13,95,114,101,115,111,108,118,101,95,110,97,109, - 101,134,3,0,0,115,10,0,0,0,16,2,12,1,8,1, - 8,1,20,1,114,211,0,0,0,99,3,0,0,0,0,0, - 0,0,0,0,0,0,5,0,0,0,4,0,0,0,67,0, - 0,0,115,60,0,0,0,116,0,124,0,131,1,155,0,100, - 1,157,2,125,3,116,1,160,2,124,3,116,3,161,2,1, - 0,124,0,160,4,124,1,124,2,161,2,125,4,124,4,100, - 0,117,0,114,25,100,0,83,0,116,5,124,1,124,4,131, - 2,83,0,41,2,78,122,53,46,102,105,110,100,95,115,112, - 101,99,40,41,32,110,111,116,32,102,111,117,110,100,59,32, - 102,97,108,108,105,110,103,32,98,97,99,107,32,116,111,32, - 102,105,110,100,95,109,111,100,117,108,101,40,41,41,6,114, - 7,0,0,0,114,101,0,0,0,114,102,0,0,0,114,169, - 0,0,0,114,184,0,0,0,114,104,0,0,0,41,5,218, - 6,102,105,110,100,101,114,114,20,0,0,0,114,181,0,0, - 0,114,108,0,0,0,114,122,0,0,0,114,5,0,0,0, - 114,5,0,0,0,114,6,0,0,0,218,17,95,102,105,110, - 100,95,115,112,101,99,95,108,101,103,97,99,121,143,3,0, - 0,115,12,0,0,0,14,1,12,2,12,1,8,1,4,1, - 10,1,114,213,0,0,0,99,3,0,0,0,0,0,0,0, - 0,0,0,0,10,0,0,0,10,0,0,0,67,0,0,0, - 115,24,1,0,0,116,0,106,1,125,3,124,3,100,1,117, - 0,114,11,116,2,100,2,131,1,130,1,124,3,115,19,116, - 3,160,4,100,3,116,5,161,2,1,0,124,0,116,0,106, - 6,118,0,125,4,124,3,68,0,93,111,125,5,116,7,131, - 0,143,47,1,0,122,5,124,5,106,8,125,6,87,0,110, - 27,4,0,116,9,121,64,1,0,1,0,1,0,116,10,124, - 5,124,0,124,1,131,3,125,7,124,7,100,1,117,0,114, - 62,89,0,87,0,100,1,4,0,4,0,131,3,1,0,113, - 26,89,0,110,7,119,0,124,6,124,0,124,1,124,2,131, - 3,125,7,87,0,100,1,4,0,4,0,131,3,1,0,110, - 8,49,0,115,81,119,1,1,0,1,0,1,0,89,0,1, - 0,124,7,100,1,117,1,114,137,124,4,115,133,124,0,116, - 0,106,6,118,0,114,133,116,0,106,6,124,0,25,0,125, - 8,122,5,124,8,106,11,125,9,87,0,110,13,4,0,116, - 9,121,120,1,0,1,0,1,0,124,7,6,0,89,0,2, - 0,1,0,83,0,119,0,124,9,100,1,117,0,114,129,124, - 7,2,0,1,0,83,0,124,9,2,0,1,0,83,0,124, - 7,2,0,1,0,83,0,113,26,100,1,83,0,41,4,122, - 21,70,105,110,100,32,97,32,109,111,100,117,108,101,39,115, - 32,115,112,101,99,46,78,122,53,115,121,115,46,109,101,116, - 97,95,112,97,116,104,32,105,115,32,78,111,110,101,44,32, - 80,121,116,104,111,110,32,105,115,32,108,105,107,101,108,121, - 32,115,104,117,116,116,105,110,103,32,100,111,119,110,122,22, - 115,121,115,46,109,101,116,97,95,112,97,116,104,32,105,115, - 32,101,109,112,116,121,41,12,114,18,0,0,0,218,9,109, - 101,116,97,95,112,97,116,104,114,87,0,0,0,114,101,0, - 0,0,114,102,0,0,0,114,169,0,0,0,114,105,0,0, - 0,114,200,0,0,0,114,183,0,0,0,114,2,0,0,0, - 114,213,0,0,0,114,113,0,0,0,41,10,114,20,0,0, - 0,114,181,0,0,0,114,182,0,0,0,114,214,0,0,0, - 90,9,105,115,95,114,101,108,111,97,100,114,212,0,0,0, - 114,183,0,0,0,114,109,0,0,0,114,110,0,0,0,114, - 113,0,0,0,114,5,0,0,0,114,5,0,0,0,114,6, - 0,0,0,218,10,95,102,105,110,100,95,115,112,101,99,153, - 3,0,0,115,68,0,0,0,6,2,8,1,8,2,4,3, - 12,1,10,5,8,1,8,1,2,1,10,1,12,1,12,1, - 8,1,2,1,14,250,4,5,2,254,12,5,2,128,28,248, - 8,9,14,2,10,1,2,1,10,1,12,1,12,4,2,252, - 8,6,8,1,8,2,8,2,2,239,4,19,114,215,0,0, - 0,99,3,0,0,0,0,0,0,0,0,0,0,0,3,0, - 0,0,5,0,0,0,67,0,0,0,115,110,0,0,0,116, - 0,124,0,116,1,131,2,115,14,116,2,100,1,160,3,116, - 4,124,0,131,1,161,1,131,1,130,1,124,2,100,2,107, - 0,114,22,116,5,100,3,131,1,130,1,124,2,100,2,107, - 4,114,41,116,0,124,1,116,1,131,2,115,35,116,2,100, - 4,131,1,130,1,124,1,115,41,116,6,100,5,131,1,130, - 1,124,0,115,51,124,2,100,2,107,2,114,53,116,5,100, - 6,131,1,130,1,100,7,83,0,100,7,83,0,41,8,122, - 28,86,101,114,105,102,121,32,97,114,103,117,109,101,110,116, - 115,32,97,114,101,32,34,115,97,110,101,34,46,122,31,109, - 111,100,117,108,101,32,110,97,109,101,32,109,117,115,116,32, - 98,101,32,115,116,114,44,32,110,111,116,32,123,125,114,25, - 0,0,0,122,18,108,101,118,101,108,32,109,117,115,116,32, - 98,101,32,62,61,32,48,122,31,95,95,112,97,99,107,97, - 103,101,95,95,32,110,111,116,32,115,101,116,32,116,111,32, - 97,32,115,116,114,105,110,103,122,54,97,116,116,101,109,112, - 116,101,100,32,114,101,108,97,116,105,118,101,32,105,109,112, - 111,114,116,32,119,105,116,104,32,110,111,32,107,110,111,119, - 110,32,112,97,114,101,110,116,32,112,97,99,107,97,103,101, - 122,17,69,109,112,116,121,32,109,111,100,117,108,101,32,110, - 97,109,101,78,41,7,218,10,105,115,105,110,115,116,97,110, - 99,101,218,3,115,116,114,218,9,84,121,112,101,69,114,114, - 111,114,114,50,0,0,0,114,3,0,0,0,218,10,86,97, - 108,117,101,69,114,114,111,114,114,87,0,0,0,169,3,114, - 20,0,0,0,114,209,0,0,0,114,210,0,0,0,114,5, - 0,0,0,114,5,0,0,0,114,6,0,0,0,218,13,95, - 115,97,110,105,116,121,95,99,104,101,99,107,200,3,0,0, - 115,24,0,0,0,10,2,18,1,8,1,8,1,8,1,10, - 1,8,1,4,1,8,1,12,2,8,1,8,255,114,221,0, - 0,0,122,16,78,111,32,109,111,100,117,108,101,32,110,97, - 109,101,100,32,122,4,123,33,114,125,99,2,0,0,0,0, - 0,0,0,0,0,0,0,9,0,0,0,8,0,0,0,67, - 0,0,0,115,16,1,0,0,100,0,125,2,124,0,160,0, - 100,1,161,1,100,2,25,0,125,3,124,3,114,64,124,3, - 116,1,106,2,118,1,114,21,116,3,124,1,124,3,131,2, - 1,0,124,0,116,1,106,2,118,0,114,31,116,1,106,2, - 124,0,25,0,83,0,116,1,106,2,124,3,25,0,125,4, - 122,5,124,4,106,4,125,2,87,0,110,22,4,0,116,5, - 121,63,1,0,1,0,1,0,116,6,100,3,23,0,160,7, - 124,0,124,3,161,2,125,5,116,8,124,5,124,0,100,4, - 141,2,100,0,130,2,119,0,116,9,124,0,124,2,131,2, - 125,6,124,6,100,0,117,0,114,82,116,8,116,6,160,7, - 124,0,161,1,124,0,100,4,141,2,130,1,116,10,124,6, - 131,1,125,7,124,3,114,134,116,1,106,2,124,3,25,0, - 125,4,124,0,160,0,100,1,161,1,100,5,25,0,125,8, - 122,9,116,11,124,4,124,8,124,7,131,3,1,0,87,0, - 124,7,83,0,4,0,116,5,121,133,1,0,1,0,1,0, - 100,6,124,3,155,2,100,7,124,8,155,2,157,4,125,5, - 116,12,160,13,124,5,116,14,161,2,1,0,89,0,124,7, - 83,0,119,0,124,7,83,0,41,8,78,114,141,0,0,0, - 114,25,0,0,0,122,23,59,32,123,33,114,125,32,105,115, - 32,110,111,116,32,97,32,112,97,99,107,97,103,101,114,19, - 0,0,0,233,2,0,0,0,122,27,67,97,110,110,111,116, - 32,115,101,116,32,97,110,32,97,116,116,114,105,98,117,116, - 101,32,111,110,32,122,18,32,102,111,114,32,99,104,105,108, - 100,32,109,111,100,117,108,101,32,41,15,114,142,0,0,0, - 114,18,0,0,0,114,105,0,0,0,114,74,0,0,0,114, - 154,0,0,0,114,2,0,0,0,218,8,95,69,82,82,95, - 77,83,71,114,50,0,0,0,218,19,77,111,100,117,108,101, - 78,111,116,70,111,117,110,100,69,114,114,111,114,114,215,0, - 0,0,114,173,0,0,0,114,12,0,0,0,114,101,0,0, - 0,114,102,0,0,0,114,169,0,0,0,41,9,114,20,0, - 0,0,218,7,105,109,112,111,114,116,95,114,181,0,0,0, - 114,143,0,0,0,90,13,112,97,114,101,110,116,95,109,111, - 100,117,108,101,114,108,0,0,0,114,109,0,0,0,114,110, - 0,0,0,90,5,99,104,105,108,100,114,5,0,0,0,114, - 5,0,0,0,114,6,0,0,0,218,23,95,102,105,110,100, - 95,97,110,100,95,108,111,97,100,95,117,110,108,111,99,107, - 101,100,219,3,0,0,115,60,0,0,0,4,1,14,1,4, - 1,10,1,10,1,10,2,10,1,10,1,2,1,10,1,12, - 1,16,1,14,1,2,254,10,3,8,1,18,1,8,2,4, - 1,10,2,14,1,2,1,14,1,4,4,12,253,16,1,14, - 1,4,1,2,253,4,3,114,226,0,0,0,99,2,0,0, - 0,0,0,0,0,0,0,0,0,4,0,0,0,8,0,0, - 0,67,0,0,0,115,128,0,0,0,116,0,124,0,131,1, - 143,31,1,0,116,1,106,2,160,3,124,0,116,4,161,2, - 125,2,124,2,116,4,117,0,114,28,116,5,124,0,124,1, - 131,2,87,0,2,0,100,1,4,0,4,0,131,3,1,0, - 83,0,87,0,100,1,4,0,4,0,131,3,1,0,110,8, - 49,0,115,38,119,1,1,0,1,0,1,0,89,0,1,0, - 124,2,100,1,117,0,114,58,100,2,160,6,124,0,161,1, - 125,3,116,7,124,3,124,0,100,3,141,2,130,1,116,8, - 124,0,131,1,1,0,124,2,83,0,41,4,122,25,70,105, - 110,100,32,97,110,100,32,108,111,97,100,32,116,104,101,32, - 109,111,100,117,108,101,46,78,122,40,105,109,112,111,114,116, - 32,111,102,32,123,125,32,104,97,108,116,101,100,59,32,78, - 111,110,101,32,105,110,32,115,121,115,46,109,111,100,117,108, - 101,115,114,19,0,0,0,41,9,114,57,0,0,0,114,18, - 0,0,0,114,105,0,0,0,114,38,0,0,0,218,14,95, - 78,69,69,68,83,95,76,79,65,68,73,78,71,114,226,0, - 0,0,114,50,0,0,0,114,224,0,0,0,114,72,0,0, - 0,41,4,114,20,0,0,0,114,225,0,0,0,114,110,0, - 0,0,114,82,0,0,0,114,5,0,0,0,114,5,0,0, - 0,114,6,0,0,0,218,14,95,102,105,110,100,95,97,110, - 100,95,108,111,97,100,254,3,0,0,115,28,0,0,0,10, - 2,14,1,8,1,8,1,16,253,2,2,28,254,8,5,2, - 1,6,1,2,255,12,2,8,2,4,1,114,228,0,0,0, - 114,25,0,0,0,99,3,0,0,0,0,0,0,0,0,0, - 0,0,3,0,0,0,4,0,0,0,67,0,0,0,115,42, - 0,0,0,116,0,124,0,124,1,124,2,131,3,1,0,124, - 2,100,1,107,4,114,16,116,1,124,0,124,1,124,2,131, - 3,125,0,116,2,124,0,116,3,131,2,83,0,41,2,97, - 50,1,0,0,73,109,112,111,114,116,32,97,110,100,32,114, - 101,116,117,114,110,32,116,104,101,32,109,111,100,117,108,101, - 32,98,97,115,101,100,32,111,110,32,105,116,115,32,110,97, - 109,101,44,32,116,104,101,32,112,97,99,107,97,103,101,32, - 116,104,101,32,99,97,108,108,32,105,115,10,32,32,32,32, - 98,101,105,110,103,32,109,97,100,101,32,102,114,111,109,44, - 32,97,110,100,32,116,104,101,32,108,101,118,101,108,32,97, - 100,106,117,115,116,109,101,110,116,46,10,10,32,32,32,32, - 84,104,105,115,32,102,117,110,99,116,105,111,110,32,114,101, - 112,114,101,115,101,110,116,115,32,116,104,101,32,103,114,101, - 97,116,101,115,116,32,99,111,109,109,111,110,32,100,101,110, - 111,109,105,110,97,116,111,114,32,111,102,32,102,117,110,99, - 116,105,111,110,97,108,105,116,121,10,32,32,32,32,98,101, - 116,119,101,101,110,32,105,109,112,111,114,116,95,109,111,100, - 117,108,101,32,97,110,100,32,95,95,105,109,112,111,114,116, - 95,95,46,32,84,104,105,115,32,105,110,99,108,117,100,101, - 115,32,115,101,116,116,105,110,103,32,95,95,112,97,99,107, - 97,103,101,95,95,32,105,102,10,32,32,32,32,116,104,101, - 32,108,111,97,100,101,114,32,100,105,100,32,110,111,116,46, - 10,10,32,32,32,32,114,25,0,0,0,41,4,114,221,0, - 0,0,114,211,0,0,0,114,228,0,0,0,218,11,95,103, - 99,100,95,105,109,112,111,114,116,114,220,0,0,0,114,5, - 0,0,0,114,5,0,0,0,114,6,0,0,0,114,229,0, - 0,0,14,4,0,0,115,8,0,0,0,12,9,8,1,12, - 1,10,1,114,229,0,0,0,169,1,218,9,114,101,99,117, - 114,115,105,118,101,99,3,0,0,0,0,0,0,0,1,0, - 0,0,8,0,0,0,11,0,0,0,67,0,0,0,115,218, - 0,0,0,124,1,68,0,93,104,125,4,116,0,124,4,116, - 1,131,2,115,32,124,3,114,17,124,0,106,2,100,1,23, - 0,125,5,110,2,100,2,125,5,116,3,100,3,124,5,155, - 0,100,4,116,4,124,4,131,1,106,2,155,0,157,4,131, - 1,130,1,124,4,100,5,107,2,114,53,124,3,115,52,116, - 5,124,0,100,6,131,2,114,52,116,6,124,0,124,0,106, - 7,124,2,100,7,100,8,141,4,1,0,113,2,116,5,124, - 0,124,4,131,2,115,106,100,9,160,8,124,0,106,2,124, - 4,161,2,125,6,122,7,116,9,124,2,124,6,131,2,1, - 0,87,0,113,2,4,0,116,10,121,105,1,0,125,7,1, - 0,122,21,124,7,106,11,124,6,107,2,114,100,116,12,106, - 13,160,14,124,6,116,15,161,2,100,10,117,1,114,100,87, - 0,89,0,100,10,125,7,126,7,113,2,130,0,100,10,125, - 7,126,7,119,1,119,0,113,2,124,0,83,0,41,11,122, - 238,70,105,103,117,114,101,32,111,117,116,32,119,104,97,116, - 32,95,95,105,109,112,111,114,116,95,95,32,115,104,111,117, - 108,100,32,114,101,116,117,114,110,46,10,10,32,32,32,32, - 84,104,101,32,105,109,112,111,114,116,95,32,112,97,114,97, - 109,101,116,101,114,32,105,115,32,97,32,99,97,108,108,97, - 98,108,101,32,119,104,105,99,104,32,116,97,107,101,115,32, - 116,104,101,32,110,97,109,101,32,111,102,32,109,111,100,117, - 108,101,32,116,111,10,32,32,32,32,105,109,112,111,114,116, - 46,32,73,116,32,105,115,32,114,101,113,117,105,114,101,100, - 32,116,111,32,100,101,99,111,117,112,108,101,32,116,104,101, - 32,102,117,110,99,116,105,111,110,32,102,114,111,109,32,97, - 115,115,117,109,105,110,103,32,105,109,112,111,114,116,108,105, - 98,39,115,10,32,32,32,32,105,109,112,111,114,116,32,105, - 109,112,108,101,109,101,110,116,97,116,105,111,110,32,105,115, - 32,100,101,115,105,114,101,100,46,10,10,32,32,32,32,122, - 8,46,95,95,97,108,108,95,95,122,13,96,96,102,114,111, - 109,32,108,105,115,116,39,39,122,8,73,116,101,109,32,105, - 110,32,122,18,32,109,117,115,116,32,98,101,32,115,116,114, - 44,32,110,111,116,32,250,1,42,218,7,95,95,97,108,108, - 95,95,84,114,230,0,0,0,114,206,0,0,0,78,41,16, - 114,216,0,0,0,114,217,0,0,0,114,9,0,0,0,114, - 218,0,0,0,114,3,0,0,0,114,11,0,0,0,218,16, - 95,104,97,110,100,108,101,95,102,114,111,109,108,105,115,116, - 114,233,0,0,0,114,50,0,0,0,114,74,0,0,0,114, - 224,0,0,0,114,20,0,0,0,114,18,0,0,0,114,105, - 0,0,0,114,38,0,0,0,114,227,0,0,0,41,8,114, - 110,0,0,0,218,8,102,114,111,109,108,105,115,116,114,225, - 0,0,0,114,231,0,0,0,218,1,120,90,5,119,104,101, - 114,101,90,9,102,114,111,109,95,110,97,109,101,90,3,101, - 120,99,114,5,0,0,0,114,5,0,0,0,114,6,0,0, - 0,114,234,0,0,0,29,4,0,0,115,56,0,0,0,8, - 10,10,1,4,1,12,1,4,2,10,1,8,1,8,255,8, - 2,14,1,10,1,2,1,6,255,2,128,10,2,14,1,2, - 1,14,1,14,1,10,4,16,1,2,255,12,2,2,1,8, - 128,2,249,2,252,4,12,114,234,0,0,0,99,1,0,0, - 0,0,0,0,0,0,0,0,0,3,0,0,0,6,0,0, - 0,67,0,0,0,115,146,0,0,0,124,0,160,0,100,1, - 161,1,125,1,124,0,160,0,100,2,161,1,125,2,124,1, - 100,3,117,1,114,41,124,2,100,3,117,1,114,39,124,1, - 124,2,106,1,107,3,114,39,116,2,106,3,100,4,124,1, - 155,2,100,5,124,2,106,1,155,2,100,6,157,5,116,4, - 100,7,100,8,141,3,1,0,124,1,83,0,124,2,100,3, - 117,1,114,48,124,2,106,1,83,0,116,2,106,3,100,9, - 116,4,100,7,100,8,141,3,1,0,124,0,100,10,25,0, - 125,1,100,11,124,0,118,1,114,71,124,1,160,5,100,12, - 161,1,100,13,25,0,125,1,124,1,83,0,41,14,122,167, - 67,97,108,99,117,108,97,116,101,32,119,104,97,116,32,95, - 95,112,97,99,107,97,103,101,95,95,32,115,104,111,117,108, - 100,32,98,101,46,10,10,32,32,32,32,95,95,112,97,99, - 107,97,103,101,95,95,32,105,115,32,110,111,116,32,103,117, - 97,114,97,110,116,101,101,100,32,116,111,32,98,101,32,100, - 101,102,105,110,101,100,32,111,114,32,99,111,117,108,100,32, - 98,101,32,115,101,116,32,116,111,32,78,111,110,101,10,32, - 32,32,32,116,111,32,114,101,112,114,101,115,101,110,116,32, - 116,104,97,116,32,105,116,115,32,112,114,111,112,101,114,32, - 118,97,108,117,101,32,105,115,32,117,110,107,110,111,119,110, - 46,10,10,32,32,32,32,114,158,0,0,0,114,113,0,0, - 0,78,122,32,95,95,112,97,99,107,97,103,101,95,95,32, - 33,61,32,95,95,115,112,101,99,95,95,46,112,97,114,101, - 110,116,32,40,122,4,32,33,61,32,250,1,41,233,3,0, - 0,0,41,1,90,10,115,116,97,99,107,108,101,118,101,108, - 122,89,99,97,110,39,116,32,114,101,115,111,108,118,101,32, - 112,97,99,107,97,103,101,32,102,114,111,109,32,95,95,115, - 112,101,99,95,95,32,111,114,32,95,95,112,97,99,107,97, - 103,101,95,95,44,32,102,97,108,108,105,110,103,32,98,97, - 99,107,32,111,110,32,95,95,110,97,109,101,95,95,32,97, - 110,100,32,95,95,112,97,116,104,95,95,114,9,0,0,0, - 114,154,0,0,0,114,141,0,0,0,114,25,0,0,0,41, - 6,114,38,0,0,0,114,143,0,0,0,114,101,0,0,0, - 114,102,0,0,0,114,169,0,0,0,114,142,0,0,0,41, - 3,218,7,103,108,111,98,97,108,115,114,209,0,0,0,114, - 109,0,0,0,114,5,0,0,0,114,5,0,0,0,114,6, - 0,0,0,218,17,95,99,97,108,99,95,95,95,112,97,99, - 107,97,103,101,95,95,66,4,0,0,115,42,0,0,0,10, - 7,10,1,8,1,18,1,6,1,2,1,4,255,4,1,6, - 255,4,2,6,254,4,3,8,1,6,1,6,2,4,2,6, - 254,8,3,8,1,14,1,4,1,114,240,0,0,0,114,5, - 0,0,0,99,5,0,0,0,0,0,0,0,0,0,0,0, - 9,0,0,0,5,0,0,0,67,0,0,0,115,174,0,0, - 0,124,4,100,1,107,2,114,9,116,0,124,0,131,1,125, - 5,110,18,124,1,100,2,117,1,114,15,124,1,110,1,105, - 0,125,6,116,1,124,6,131,1,125,7,116,0,124,0,124, - 7,124,4,131,3,125,5,124,3,115,74,124,4,100,1,107, - 2,114,42,116,0,124,0,160,2,100,3,161,1,100,1,25, - 0,131,1,83,0,124,0,115,46,124,5,83,0,116,3,124, - 0,131,1,116,3,124,0,160,2,100,3,161,1,100,1,25, - 0,131,1,24,0,125,8,116,4,106,5,124,5,106,6,100, - 2,116,3,124,5,106,6,131,1,124,8,24,0,133,2,25, - 0,25,0,83,0,116,7,124,5,100,4,131,2,114,85,116, - 8,124,5,124,3,116,0,131,3,83,0,124,5,83,0,41, - 5,97,215,1,0,0,73,109,112,111,114,116,32,97,32,109, - 111,100,117,108,101,46,10,10,32,32,32,32,84,104,101,32, - 39,103,108,111,98,97,108,115,39,32,97,114,103,117,109,101, - 110,116,32,105,115,32,117,115,101,100,32,116,111,32,105,110, - 102,101,114,32,119,104,101,114,101,32,116,104,101,32,105,109, - 112,111,114,116,32,105,115,32,111,99,99,117,114,114,105,110, - 103,32,102,114,111,109,10,32,32,32,32,116,111,32,104,97, - 110,100,108,101,32,114,101,108,97,116,105,118,101,32,105,109, - 112,111,114,116,115,46,32,84,104,101,32,39,108,111,99,97, - 108,115,39,32,97,114,103,117,109,101,110,116,32,105,115,32, - 105,103,110,111,114,101,100,46,32,84,104,101,10,32,32,32, - 32,39,102,114,111,109,108,105,115,116,39,32,97,114,103,117, - 109,101,110,116,32,115,112,101,99,105,102,105,101,115,32,119, - 104,97,116,32,115,104,111,117,108,100,32,101,120,105,115,116, - 32,97,115,32,97,116,116,114,105,98,117,116,101,115,32,111, - 110,32,116,104,101,32,109,111,100,117,108,101,10,32,32,32, - 32,98,101,105,110,103,32,105,109,112,111,114,116,101,100,32, - 40,101,46,103,46,32,96,96,102,114,111,109,32,109,111,100, - 117,108,101,32,105,109,112,111,114,116,32,60,102,114,111,109, - 108,105,115,116,62,96,96,41,46,32,32,84,104,101,32,39, - 108,101,118,101,108,39,10,32,32,32,32,97,114,103,117,109, - 101,110,116,32,114,101,112,114,101,115,101,110,116,115,32,116, - 104,101,32,112,97,99,107,97,103,101,32,108,111,99,97,116, - 105,111,110,32,116,111,32,105,109,112,111,114,116,32,102,114, - 111,109,32,105,110,32,97,32,114,101,108,97,116,105,118,101, - 10,32,32,32,32,105,109,112,111,114,116,32,40,101,46,103, - 46,32,96,96,102,114,111,109,32,46,46,112,107,103,32,105, - 109,112,111,114,116,32,109,111,100,96,96,32,119,111,117,108, - 100,32,104,97,118,101,32,97,32,39,108,101,118,101,108,39, - 32,111,102,32,50,41,46,10,10,32,32,32,32,114,25,0, - 0,0,78,114,141,0,0,0,114,154,0,0,0,41,9,114, - 229,0,0,0,114,240,0,0,0,218,9,112,97,114,116,105, - 116,105,111,110,114,208,0,0,0,114,18,0,0,0,114,105, - 0,0,0,114,9,0,0,0,114,11,0,0,0,114,234,0, - 0,0,41,9,114,20,0,0,0,114,239,0,0,0,218,6, - 108,111,99,97,108,115,114,235,0,0,0,114,210,0,0,0, - 114,110,0,0,0,90,8,103,108,111,98,97,108,115,95,114, - 209,0,0,0,90,7,99,117,116,95,111,102,102,114,5,0, - 0,0,114,5,0,0,0,114,6,0,0,0,218,10,95,95, - 105,109,112,111,114,116,95,95,93,4,0,0,115,30,0,0, - 0,8,11,10,1,16,2,8,1,12,1,4,1,8,3,18, - 1,4,1,4,1,26,4,30,3,10,1,12,1,4,2,114, - 243,0,0,0,99,1,0,0,0,0,0,0,0,0,0,0, - 0,2,0,0,0,3,0,0,0,67,0,0,0,115,38,0, - 0,0,116,0,160,1,124,0,161,1,125,1,124,1,100,0, - 117,0,114,15,116,2,100,1,124,0,23,0,131,1,130,1, - 116,3,124,1,131,1,83,0,41,2,78,122,25,110,111,32, - 98,117,105,108,116,45,105,110,32,109,111,100,117,108,101,32, - 110,97,109,101,100,32,41,4,114,175,0,0,0,114,183,0, - 0,0,114,87,0,0,0,114,173,0,0,0,41,2,114,20, - 0,0,0,114,109,0,0,0,114,5,0,0,0,114,5,0, - 0,0,114,6,0,0,0,218,18,95,98,117,105,108,116,105, - 110,95,102,114,111,109,95,110,97,109,101,130,4,0,0,115, - 8,0,0,0,10,1,8,1,12,1,8,1,114,244,0,0, - 0,99,2,0,0,0,0,0,0,0,0,0,0,0,10,0, - 0,0,5,0,0,0,67,0,0,0,115,166,0,0,0,124, - 1,97,0,124,0,97,1,116,2,116,1,131,1,125,2,116, - 1,106,3,160,4,161,0,68,0,93,36,92,2,125,3,125, - 4,116,5,124,4,124,2,131,2,114,49,124,3,116,1,106, - 6,118,0,114,30,116,7,125,5,110,9,116,0,160,8,124, - 3,161,1,114,38,116,9,125,5,110,1,113,13,116,10,124, - 4,124,5,131,2,125,6,116,11,124,6,124,4,131,2,1, - 0,113,13,116,1,106,3,116,12,25,0,125,7,100,1,68, - 0,93,23,125,8,124,8,116,1,106,3,118,1,114,69,116, - 13,124,8,131,1,125,9,110,5,116,1,106,3,124,8,25, - 0,125,9,116,14,124,7,124,8,124,9,131,3,1,0,113, - 57,100,2,83,0,41,3,122,250,83,101,116,117,112,32,105, - 109,112,111,114,116,108,105,98,32,98,121,32,105,109,112,111, - 114,116,105,110,103,32,110,101,101,100,101,100,32,98,117,105, - 108,116,45,105,110,32,109,111,100,117,108,101,115,32,97,110, - 100,32,105,110,106,101,99,116,105,110,103,32,116,104,101,109, - 10,32,32,32,32,105,110,116,111,32,116,104,101,32,103,108, - 111,98,97,108,32,110,97,109,101,115,112,97,99,101,46,10, - 10,32,32,32,32,65,115,32,115,121,115,32,105,115,32,110, - 101,101,100,101,100,32,102,111,114,32,115,121,115,46,109,111, - 100,117,108,101,115,32,97,99,99,101,115,115,32,97,110,100, - 32,95,105,109,112,32,105,115,32,110,101,101,100,101,100,32, - 116,111,32,108,111,97,100,32,98,117,105,108,116,45,105,110, - 10,32,32,32,32,109,111,100,117,108,101,115,44,32,116,104, - 111,115,101,32,116,119,111,32,109,111,100,117,108,101,115,32, - 109,117,115,116,32,98,101,32,101,120,112,108,105,99,105,116, - 108,121,32,112,97,115,115,101,100,32,105,110,46,10,10,32, - 32,32,32,41,3,114,26,0,0,0,114,101,0,0,0,114, - 71,0,0,0,78,41,15,114,64,0,0,0,114,18,0,0, - 0,114,3,0,0,0,114,105,0,0,0,218,5,105,116,101, - 109,115,114,216,0,0,0,114,86,0,0,0,114,175,0,0, - 0,114,98,0,0,0,114,193,0,0,0,114,155,0,0,0, - 114,161,0,0,0,114,9,0,0,0,114,244,0,0,0,114, - 12,0,0,0,41,10,218,10,115,121,115,95,109,111,100,117, - 108,101,218,11,95,105,109,112,95,109,111,100,117,108,101,90, - 11,109,111,100,117,108,101,95,116,121,112,101,114,20,0,0, - 0,114,110,0,0,0,114,122,0,0,0,114,109,0,0,0, - 90,11,115,101,108,102,95,109,111,100,117,108,101,90,12,98, - 117,105,108,116,105,110,95,110,97,109,101,90,14,98,117,105, - 108,116,105,110,95,109,111,100,117,108,101,114,5,0,0,0, - 114,5,0,0,0,114,6,0,0,0,218,6,95,115,101,116, - 117,112,137,4,0,0,115,40,0,0,0,4,9,4,1,8, - 3,18,1,10,1,10,1,6,1,10,1,6,1,2,2,10, - 1,10,1,2,128,10,3,8,1,10,1,10,1,10,2,14, - 1,4,251,114,248,0,0,0,99,2,0,0,0,0,0,0, - 0,0,0,0,0,2,0,0,0,3,0,0,0,67,0,0, - 0,115,38,0,0,0,116,0,124,0,124,1,131,2,1,0, - 116,1,106,2,160,3,116,4,161,1,1,0,116,1,106,2, - 160,3,116,5,161,1,1,0,100,1,83,0,41,2,122,48, - 73,110,115,116,97,108,108,32,105,109,112,111,114,116,101,114, - 115,32,102,111,114,32,98,117,105,108,116,105,110,32,97,110, - 100,32,102,114,111,122,101,110,32,109,111,100,117,108,101,115, - 78,41,6,114,248,0,0,0,114,18,0,0,0,114,214,0, - 0,0,114,132,0,0,0,114,175,0,0,0,114,193,0,0, - 0,41,2,114,246,0,0,0,114,247,0,0,0,114,5,0, - 0,0,114,5,0,0,0,114,6,0,0,0,218,8,95,105, - 110,115,116,97,108,108,172,4,0,0,115,6,0,0,0,10, - 2,12,2,16,1,114,249,0,0,0,99,0,0,0,0,0, - 0,0,0,0,0,0,0,1,0,0,0,4,0,0,0,67, - 0,0,0,115,32,0,0,0,100,1,100,2,108,0,125,0, - 124,0,97,1,124,0,160,2,116,3,106,4,116,5,25,0, - 161,1,1,0,100,2,83,0,41,3,122,57,73,110,115,116, - 97,108,108,32,105,109,112,111,114,116,101,114,115,32,116,104, - 97,116,32,114,101,113,117,105,114,101,32,101,120,116,101,114, - 110,97,108,32,102,105,108,101,115,121,115,116,101,109,32,97, - 99,99,101,115,115,114,25,0,0,0,78,41,6,218,26,95, - 102,114,111,122,101,110,95,105,109,112,111,114,116,108,105,98, - 95,101,120,116,101,114,110,97,108,114,139,0,0,0,114,249, - 0,0,0,114,18,0,0,0,114,105,0,0,0,114,9,0, - 0,0,41,1,114,250,0,0,0,114,5,0,0,0,114,5, - 0,0,0,114,6,0,0,0,218,27,95,105,110,115,116,97, - 108,108,95,101,120,116,101,114,110,97,108,95,105,109,112,111, - 114,116,101,114,115,180,4,0,0,115,6,0,0,0,8,3, - 4,1,20,1,114,251,0,0,0,114,190,0,0,0,114,0, - 0,0,0,114,24,0,0,0,41,4,78,78,114,5,0,0, - 0,114,25,0,0,0,41,54,114,10,0,0,0,114,7,0, - 0,0,114,26,0,0,0,114,101,0,0,0,114,71,0,0, - 0,114,139,0,0,0,114,17,0,0,0,114,21,0,0,0, - 114,66,0,0,0,114,37,0,0,0,114,47,0,0,0,114, - 22,0,0,0,114,23,0,0,0,114,55,0,0,0,114,57, - 0,0,0,114,60,0,0,0,114,72,0,0,0,114,74,0, - 0,0,114,83,0,0,0,114,95,0,0,0,114,100,0,0, - 0,114,111,0,0,0,114,124,0,0,0,114,125,0,0,0, - 114,104,0,0,0,114,155,0,0,0,114,161,0,0,0,114, - 165,0,0,0,114,119,0,0,0,114,106,0,0,0,114,172, - 0,0,0,114,173,0,0,0,114,107,0,0,0,114,175,0, - 0,0,114,193,0,0,0,114,200,0,0,0,114,211,0,0, - 0,114,213,0,0,0,114,215,0,0,0,114,221,0,0,0, - 90,15,95,69,82,82,95,77,83,71,95,80,82,69,70,73, - 88,114,223,0,0,0,114,226,0,0,0,218,6,111,98,106, - 101,99,116,114,227,0,0,0,114,228,0,0,0,114,229,0, - 0,0,114,234,0,0,0,114,240,0,0,0,114,243,0,0, - 0,114,244,0,0,0,114,248,0,0,0,114,249,0,0,0, - 114,251,0,0,0,114,5,0,0,0,114,5,0,0,0,114, - 5,0,0,0,114,6,0,0,0,218,8,60,109,111,100,117, - 108,101,62,1,0,0,0,115,104,0,0,0,4,0,8,22, - 4,9,4,1,4,1,4,3,8,3,8,8,4,8,4,2, - 16,3,14,4,14,77,14,21,8,16,8,37,8,17,14,11, - 8,8,8,11,8,12,8,19,14,26,16,101,10,26,14,45, - 8,72,8,17,8,17,8,30,8,36,8,45,14,15,14,80, - 14,85,8,13,8,9,10,10,8,47,4,16,8,1,8,2, - 6,32,8,3,10,16,14,15,8,37,10,27,8,37,8,7, - 8,35,12,8, -}; diff --git a/contrib/tools/python3/src/Python/importlib_external.h b/contrib/tools/python3/src/Python/importlib_external.h deleted file mode 100644 index dcf5505fa74..00000000000 --- a/contrib/tools/python3/src/Python/importlib_external.h +++ /dev/null @@ -1,2771 +0,0 @@ -/* Auto-generated by Programs/_freeze_importlib.c */ -const unsigned char _Py_M__importlib_bootstrap_external[] = { - 99,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,5,0,0,0,64,0,0,0,115,250,2,0,0,100,0, - 90,0,100,1,97,1,100,2,100,1,108,2,90,2,100,2, - 100,1,108,3,90,3,100,2,100,1,108,4,90,4,100,2, - 100,1,108,5,90,5,100,2,100,1,108,6,90,6,101,4, - 106,7,100,3,107,2,90,8,101,8,114,40,100,2,100,1, - 108,9,90,10,100,2,100,1,108,11,90,11,110,4,100,2, - 100,1,108,12,90,10,101,8,114,51,100,4,100,5,103,2, - 90,13,110,3,100,5,103,1,90,13,101,14,100,6,100,7, - 132,0,101,13,68,0,131,1,131,1,115,65,74,0,130,1, - 101,13,100,2,25,0,90,15,101,16,101,13,131,1,90,17, - 100,8,160,18,101,13,161,1,90,13,100,9,100,10,132,0, - 101,13,68,0,131,1,90,19,100,11,90,20,100,12,90,21, - 101,21,101,20,23,0,90,22,100,13,100,14,132,0,90,23, - 101,23,131,0,90,24,100,15,100,16,132,0,90,25,100,17, - 100,18,132,0,90,26,100,19,100,20,132,0,90,27,101,8, - 114,119,100,21,100,22,132,0,90,28,110,4,100,23,100,22, - 132,0,90,28,100,24,100,25,132,0,90,29,100,26,100,27, - 132,0,90,30,100,28,100,29,132,0,90,31,100,30,100,31, - 132,0,90,32,100,32,100,33,132,0,90,33,101,8,114,150, - 100,34,100,35,132,0,90,34,110,4,100,36,100,35,132,0, - 90,34,100,112,100,38,100,39,132,1,90,35,101,36,101,35, - 106,37,131,1,90,38,100,40,160,39,100,41,100,42,161,2, - 100,43,23,0,90,40,101,41,160,42,101,40,100,42,161,2, - 90,43,100,44,90,44,100,45,90,45,100,46,103,1,90,46, - 101,8,114,192,101,46,160,47,100,47,161,1,1,0,101,2, - 160,48,161,0,90,49,100,48,103,1,90,50,101,50,4,0, - 90,51,90,52,100,113,100,1,100,49,156,1,100,50,100,51, - 132,3,90,53,100,52,100,53,132,0,90,54,100,54,100,55, - 132,0,90,55,100,56,100,57,132,0,90,56,100,58,100,59, - 132,0,90,57,100,60,100,61,132,0,90,58,100,62,100,63, - 132,0,90,59,100,64,100,65,132,0,90,60,100,66,100,67, - 132,0,90,61,100,68,100,69,132,0,90,62,100,114,100,70, - 100,71,132,1,90,63,100,115,100,72,100,73,132,1,90,64, - 100,116,100,75,100,76,132,1,90,65,100,77,100,78,132,0, - 90,66,101,67,131,0,90,68,100,113,100,1,101,68,100,79, - 156,2,100,80,100,81,132,3,90,69,71,0,100,82,100,83, - 132,0,100,83,131,2,90,70,71,0,100,84,100,85,132,0, - 100,85,131,2,90,71,71,0,100,86,100,87,132,0,100,87, - 101,71,131,3,90,72,71,0,100,88,100,89,132,0,100,89, - 131,2,90,73,71,0,100,90,100,91,132,0,100,91,101,73, - 101,72,131,4,90,74,71,0,100,92,100,93,132,0,100,93, - 101,73,101,71,131,4,90,75,71,0,100,94,100,95,132,0, - 100,95,101,73,101,71,131,4,90,76,71,0,100,96,100,97, - 132,0,100,97,131,2,90,77,71,0,100,98,100,99,132,0, - 100,99,131,2,90,78,71,0,100,100,100,101,132,0,100,101, - 131,2,90,79,71,0,100,102,100,103,132,0,100,103,131,2, - 90,80,100,113,100,104,100,105,132,1,90,81,100,106,100,107, - 132,0,90,82,100,108,100,109,132,0,90,83,100,110,100,111, - 132,0,90,84,100,1,83,0,41,117,97,94,1,0,0,67, - 111,114,101,32,105,109,112,108,101,109,101,110,116,97,116,105, - 111,110,32,111,102,32,112,97,116,104,45,98,97,115,101,100, - 32,105,109,112,111,114,116,46,10,10,84,104,105,115,32,109, - 111,100,117,108,101,32,105,115,32,78,79,84,32,109,101,97, - 110,116,32,116,111,32,98,101,32,100,105,114,101,99,116,108, - 121,32,105,109,112,111,114,116,101,100,33,32,73,116,32,104, - 97,115,32,98,101,101,110,32,100,101,115,105,103,110,101,100, - 32,115,117,99,104,10,116,104,97,116,32,105,116,32,99,97, - 110,32,98,101,32,98,111,111,116,115,116,114,97,112,112,101, - 100,32,105,110,116,111,32,80,121,116,104,111,110,32,97,115, - 32,116,104,101,32,105,109,112,108,101,109,101,110,116,97,116, - 105,111,110,32,111,102,32,105,109,112,111,114,116,46,32,65, - 115,10,115,117,99,104,32,105,116,32,114,101,113,117,105,114, - 101,115,32,116,104,101,32,105,110,106,101,99,116,105,111,110, - 32,111,102,32,115,112,101,99,105,102,105,99,32,109,111,100, - 117,108,101,115,32,97,110,100,32,97,116,116,114,105,98,117, - 116,101,115,32,105,110,32,111,114,100,101,114,32,116,111,10, - 119,111,114,107,46,32,79,110,101,32,115,104,111,117,108,100, - 32,117,115,101,32,105,109,112,111,114,116,108,105,98,32,97, - 115,32,116,104,101,32,112,117,98,108,105,99,45,102,97,99, - 105,110,103,32,118,101,114,115,105,111,110,32,111,102,32,116, - 104,105,115,32,109,111,100,117,108,101,46,10,10,78,233,0, - 0,0,0,90,5,119,105,110,51,50,250,1,92,250,1,47, - 99,1,0,0,0,0,0,0,0,0,0,0,0,2,0,0, - 0,3,0,0,0,99,0,0,0,115,28,0,0,0,129,0, - 124,0,93,9,125,1,116,0,124,1,131,1,100,0,107,2, - 86,0,1,0,113,2,100,1,83,0,41,2,233,1,0,0, - 0,78,41,1,218,3,108,101,110,41,2,218,2,46,48,218, - 3,115,101,112,169,0,114,7,0,0,0,250,38,60,102,114, - 111,122,101,110,32,105,109,112,111,114,116,108,105,98,46,95, - 98,111,111,116,115,116,114,97,112,95,101,120,116,101,114,110, - 97,108,62,218,9,60,103,101,110,101,120,112,114,62,46,0, - 0,0,115,4,0,0,0,2,128,26,0,114,9,0,0,0, - 218,0,99,1,0,0,0,0,0,0,0,0,0,0,0,2, - 0,0,0,4,0,0,0,67,0,0,0,115,22,0,0,0, - 104,0,124,0,93,7,125,1,100,0,124,1,155,0,157,2, - 146,2,113,2,83,0,41,1,250,1,58,114,7,0,0,0, - 41,2,114,5,0,0,0,218,1,115,114,7,0,0,0,114, - 7,0,0,0,114,8,0,0,0,218,9,60,115,101,116,99, - 111,109,112,62,50,0,0,0,115,2,0,0,0,22,0,114, - 13,0,0,0,41,1,218,3,119,105,110,41,2,90,6,99, - 121,103,119,105,110,90,6,100,97,114,119,105,110,99,0,0, - 0,0,0,0,0,0,0,0,0,0,1,0,0,0,3,0, - 0,0,3,0,0,0,115,62,0,0,0,116,0,106,1,160, - 2,116,3,161,1,114,25,116,0,106,1,160,2,116,4,161, - 1,114,15,100,1,137,0,110,2,100,2,137,0,135,0,102, - 1,100,3,100,4,132,8,125,0,124,0,83,0,100,5,100, - 4,132,0,125,0,124,0,83,0,41,6,78,90,12,80,89, - 84,72,79,78,67,65,83,69,79,75,115,12,0,0,0,80, - 89,84,72,79,78,67,65,83,69,79,75,99,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0, - 19,0,0,0,115,20,0,0,0,116,0,106,1,106,2,12, - 0,111,9,136,0,116,3,106,4,118,0,83,0,41,1,122, - 94,84,114,117,101,32,105,102,32,102,105,108,101,110,97,109, - 101,115,32,109,117,115,116,32,98,101,32,99,104,101,99,107, - 101,100,32,99,97,115,101,45,105,110,115,101,110,115,105,116, - 105,118,101,108,121,32,97,110,100,32,105,103,110,111,114,101, - 32,101,110,118,105,114,111,110,109,101,110,116,32,102,108,97, - 103,115,32,97,114,101,32,110,111,116,32,115,101,116,46,41, - 5,218,3,115,121,115,218,5,102,108,97,103,115,218,18,105, - 103,110,111,114,101,95,101,110,118,105,114,111,110,109,101,110, - 116,218,3,95,111,115,90,7,101,110,118,105,114,111,110,114, - 7,0,0,0,169,1,218,3,107,101,121,114,7,0,0,0, - 114,8,0,0,0,218,11,95,114,101,108,97,120,95,99,97, - 115,101,67,0,0,0,243,2,0,0,0,20,2,122,37,95, - 109,97,107,101,95,114,101,108,97,120,95,99,97,115,101,46, - 60,108,111,99,97,108,115,62,46,95,114,101,108,97,120,95, - 99,97,115,101,99,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,1,0,0,0,83,0,0,0,243,4,0, - 0,0,100,1,83,0,41,2,122,53,84,114,117,101,32,105, - 102,32,102,105,108,101,110,97,109,101,115,32,109,117,115,116, - 32,98,101,32,99,104,101,99,107,101,100,32,99,97,115,101, - 45,105,110,115,101,110,115,105,116,105,118,101,108,121,46,70, - 114,7,0,0,0,114,7,0,0,0,114,7,0,0,0,114, - 7,0,0,0,114,8,0,0,0,114,21,0,0,0,71,0, - 0,0,243,2,0,0,0,4,2,41,5,114,15,0,0,0, - 218,8,112,108,97,116,102,111,114,109,218,10,115,116,97,114, - 116,115,119,105,116,104,218,27,95,67,65,83,69,95,73,78, - 83,69,78,83,73,84,73,86,69,95,80,76,65,84,70,79, - 82,77,83,218,35,95,67,65,83,69,95,73,78,83,69,78, - 83,73,84,73,86,69,95,80,76,65,84,70,79,82,77,83, - 95,83,84,82,95,75,69,89,41,1,114,21,0,0,0,114, - 7,0,0,0,114,19,0,0,0,114,8,0,0,0,218,16, - 95,109,97,107,101,95,114,101,108,97,120,95,99,97,115,101, - 60,0,0,0,115,16,0,0,0,12,1,12,1,6,1,4, - 2,12,2,4,7,8,253,4,3,114,29,0,0,0,99,1, - 0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,4, - 0,0,0,67,0,0,0,115,20,0,0,0,116,0,124,0, - 131,1,100,1,64,0,160,1,100,2,100,3,161,2,83,0, - 41,4,122,42,67,111,110,118,101,114,116,32,97,32,51,50, - 45,98,105,116,32,105,110,116,101,103,101,114,32,116,111,32, - 108,105,116,116,108,101,45,101,110,100,105,97,110,46,236,3, - 0,0,0,255,127,255,127,3,0,233,4,0,0,0,218,6, - 108,105,116,116,108,101,41,2,218,3,105,110,116,218,8,116, - 111,95,98,121,116,101,115,41,1,218,1,120,114,7,0,0, - 0,114,7,0,0,0,114,8,0,0,0,218,12,95,112,97, - 99,107,95,117,105,110,116,51,50,79,0,0,0,114,22,0, - 0,0,114,36,0,0,0,99,1,0,0,0,0,0,0,0, - 0,0,0,0,1,0,0,0,4,0,0,0,67,0,0,0, - 243,28,0,0,0,116,0,124,0,131,1,100,1,107,2,115, - 8,74,0,130,1,116,1,160,2,124,0,100,2,161,2,83, - 0,41,3,122,47,67,111,110,118,101,114,116,32,52,32,98, - 121,116,101,115,32,105,110,32,108,105,116,116,108,101,45,101, - 110,100,105,97,110,32,116,111,32,97,110,32,105,110,116,101, - 103,101,114,46,114,31,0,0,0,114,32,0,0,0,169,3, - 114,4,0,0,0,114,33,0,0,0,218,10,102,114,111,109, - 95,98,121,116,101,115,169,1,218,4,100,97,116,97,114,7, - 0,0,0,114,7,0,0,0,114,8,0,0,0,218,14,95, - 117,110,112,97,99,107,95,117,105,110,116,51,50,84,0,0, - 0,243,4,0,0,0,16,2,12,1,114,42,0,0,0,99, - 1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0, - 4,0,0,0,67,0,0,0,114,37,0,0,0,41,3,122, - 47,67,111,110,118,101,114,116,32,50,32,98,121,116,101,115, - 32,105,110,32,108,105,116,116,108,101,45,101,110,100,105,97, - 110,32,116,111,32,97,110,32,105,110,116,101,103,101,114,46, - 233,2,0,0,0,114,32,0,0,0,114,38,0,0,0,114, - 40,0,0,0,114,7,0,0,0,114,7,0,0,0,114,8, - 0,0,0,218,14,95,117,110,112,97,99,107,95,117,105,110, - 116,49,54,89,0,0,0,114,43,0,0,0,114,45,0,0, - 0,99,0,0,0,0,0,0,0,0,0,0,0,0,5,0, - 0,0,4,0,0,0,71,0,0,0,115,228,0,0,0,124, - 0,115,4,100,1,83,0,116,0,124,0,131,1,100,2,107, - 2,114,14,124,0,100,3,25,0,83,0,100,1,125,1,103, - 0,125,2,116,1,116,2,106,3,124,0,131,2,68,0,93, - 61,92,2,125,3,125,4,124,3,160,4,116,5,161,1,115, - 38,124,3,160,6,116,5,161,1,114,51,124,3,160,7,116, - 8,161,1,112,44,124,1,125,1,116,9,124,4,23,0,103, - 1,125,2,113,24,124,3,160,6,100,4,161,1,114,76,124, - 1,160,10,161,0,124,3,160,10,161,0,107,3,114,70,124, - 3,125,1,124,4,103,1,125,2,113,24,124,2,160,11,124, - 4,161,1,1,0,113,24,124,3,112,79,124,1,125,1,124, - 2,160,11,124,4,161,1,1,0,113,24,100,5,100,6,132, - 0,124,2,68,0,131,1,125,2,116,0,124,2,131,1,100, - 2,107,2,114,107,124,2,100,3,25,0,115,107,124,1,116, - 9,23,0,83,0,124,1,116,9,160,12,124,2,161,1,23, - 0,83,0,41,7,250,31,82,101,112,108,97,99,101,109,101, - 110,116,32,102,111,114,32,111,115,46,112,97,116,104,46,106, - 111,105,110,40,41,46,114,10,0,0,0,114,3,0,0,0, - 114,0,0,0,0,114,11,0,0,0,99,1,0,0,0,0, - 0,0,0,0,0,0,0,2,0,0,0,5,0,0,0,83, - 0,0,0,243,26,0,0,0,103,0,124,0,93,9,125,1, - 124,1,114,2,124,1,160,0,116,1,161,1,145,2,113,2, - 83,0,114,7,0,0,0,169,2,218,6,114,115,116,114,105, - 112,218,15,112,97,116,104,95,115,101,112,97,114,97,116,111, - 114,115,169,2,114,5,0,0,0,218,1,112,114,7,0,0, - 0,114,7,0,0,0,114,8,0,0,0,218,10,60,108,105, - 115,116,99,111,109,112,62,119,0,0,0,115,2,0,0,0, - 26,0,250,30,95,112,97,116,104,95,106,111,105,110,46,60, - 108,111,99,97,108,115,62,46,60,108,105,115,116,99,111,109, - 112,62,41,13,114,4,0,0,0,218,3,109,97,112,114,18, - 0,0,0,218,15,95,112,97,116,104,95,115,112,108,105,116, - 114,111,111,116,114,26,0,0,0,218,14,112,97,116,104,95, - 115,101,112,95,116,117,112,108,101,218,8,101,110,100,115,119, - 105,116,104,114,49,0,0,0,114,50,0,0,0,218,8,112, - 97,116,104,95,115,101,112,218,8,99,97,115,101,102,111,108, - 100,218,6,97,112,112,101,110,100,218,4,106,111,105,110,41, - 5,218,10,112,97,116,104,95,112,97,114,116,115,218,4,114, - 111,111,116,218,4,112,97,116,104,90,8,110,101,119,95,114, - 111,111,116,218,4,116,97,105,108,114,7,0,0,0,114,7, - 0,0,0,114,8,0,0,0,218,10,95,112,97,116,104,95, - 106,111,105,110,96,0,0,0,115,42,0,0,0,4,2,4, - 1,12,1,8,1,4,1,4,1,20,1,20,1,14,1,12, - 1,10,1,16,1,4,3,8,1,12,2,8,2,12,1,14, - 1,20,1,8,2,14,1,114,67,0,0,0,99,0,0,0, - 0,0,0,0,0,0,0,0,0,1,0,0,0,4,0,0, - 0,71,0,0,0,115,20,0,0,0,116,0,160,1,100,1, - 100,2,132,0,124,0,68,0,131,1,161,1,83,0,41,3, - 114,46,0,0,0,99,1,0,0,0,0,0,0,0,0,0, - 0,0,2,0,0,0,5,0,0,0,83,0,0,0,114,47, - 0,0,0,114,7,0,0,0,114,48,0,0,0,41,2,114, - 5,0,0,0,218,4,112,97,114,116,114,7,0,0,0,114, - 7,0,0,0,114,8,0,0,0,114,53,0,0,0,128,0, - 0,0,115,6,0,0,0,6,0,4,1,16,255,114,54,0, - 0,0,41,2,114,59,0,0,0,114,62,0,0,0,41,1, - 114,63,0,0,0,114,7,0,0,0,114,7,0,0,0,114, - 8,0,0,0,114,67,0,0,0,126,0,0,0,115,6,0, - 0,0,10,2,2,1,8,255,99,1,0,0,0,0,0,0, - 0,0,0,0,0,2,0,0,0,4,0,0,0,3,0,0, - 0,115,66,0,0,0,116,0,135,0,102,1,100,1,100,2, - 132,8,116,1,68,0,131,1,131,1,125,1,124,1,100,3, - 107,0,114,19,100,4,136,0,102,2,83,0,136,0,100,5, - 124,1,133,2,25,0,136,0,124,1,100,6,23,0,100,5, - 133,2,25,0,102,2,83,0,41,7,122,32,82,101,112,108, - 97,99,101,109,101,110,116,32,102,111,114,32,111,115,46,112, - 97,116,104,46,115,112,108,105,116,40,41,46,99,1,0,0, - 0,0,0,0,0,0,0,0,0,2,0,0,0,4,0,0, - 0,51,0,0,0,115,26,0,0,0,129,0,124,0,93,8, - 125,1,136,0,160,0,124,1,161,1,86,0,1,0,113,2, - 100,0,83,0,169,1,78,41,1,218,5,114,102,105,110,100, - 114,51,0,0,0,169,1,114,65,0,0,0,114,7,0,0, - 0,114,8,0,0,0,114,9,0,0,0,134,0,0,0,115, - 4,0,0,0,2,128,24,0,122,30,95,112,97,116,104,95, - 115,112,108,105,116,46,60,108,111,99,97,108,115,62,46,60, - 103,101,110,101,120,112,114,62,114,0,0,0,0,114,10,0, - 0,0,78,114,3,0,0,0,41,2,218,3,109,97,120,114, - 50,0,0,0,41,2,114,65,0,0,0,218,1,105,114,7, - 0,0,0,114,71,0,0,0,114,8,0,0,0,218,11,95, - 112,97,116,104,95,115,112,108,105,116,132,0,0,0,115,8, - 0,0,0,22,2,8,1,8,1,28,1,114,74,0,0,0, - 99,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0, - 0,3,0,0,0,67,0,0,0,115,10,0,0,0,116,0, - 160,1,124,0,161,1,83,0,41,1,122,126,83,116,97,116, - 32,116,104,101,32,112,97,116,104,46,10,10,32,32,32,32, - 77,97,100,101,32,97,32,115,101,112,97,114,97,116,101,32, - 102,117,110,99,116,105,111,110,32,116,111,32,109,97,107,101, - 32,105,116,32,101,97,115,105,101,114,32,116,111,32,111,118, - 101,114,114,105,100,101,32,105,110,32,101,120,112,101,114,105, - 109,101,110,116,115,10,32,32,32,32,40,101,46,103,46,32, - 99,97,99,104,101,32,115,116,97,116,32,114,101,115,117,108, - 116,115,41,46,10,10,32,32,32,32,41,2,114,18,0,0, - 0,90,4,115,116,97,116,114,71,0,0,0,114,7,0,0, - 0,114,7,0,0,0,114,8,0,0,0,218,10,95,112,97, - 116,104,95,115,116,97,116,140,0,0,0,115,2,0,0,0, - 10,7,114,75,0,0,0,99,2,0,0,0,0,0,0,0, - 0,0,0,0,3,0,0,0,8,0,0,0,67,0,0,0, - 115,48,0,0,0,122,6,116,0,124,0,131,1,125,2,87, - 0,110,10,4,0,116,1,121,16,1,0,1,0,1,0,89, - 0,100,1,83,0,119,0,124,2,106,2,100,2,64,0,124, - 1,107,2,83,0,41,3,122,49,84,101,115,116,32,119,104, - 101,116,104,101,114,32,116,104,101,32,112,97,116,104,32,105, - 115,32,116,104,101,32,115,112,101,99,105,102,105,101,100,32, - 109,111,100,101,32,116,121,112,101,46,70,105,0,240,0,0, - 41,3,114,75,0,0,0,218,7,79,83,69,114,114,111,114, - 218,7,115,116,95,109,111,100,101,41,3,114,65,0,0,0, - 218,4,109,111,100,101,90,9,115,116,97,116,95,105,110,102, - 111,114,7,0,0,0,114,7,0,0,0,114,8,0,0,0, - 218,18,95,112,97,116,104,95,105,115,95,109,111,100,101,95, - 116,121,112,101,150,0,0,0,115,12,0,0,0,2,2,12, - 1,12,1,6,1,2,255,14,2,114,79,0,0,0,99,1, - 0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,3, - 0,0,0,67,0,0,0,115,10,0,0,0,116,0,124,0, - 100,1,131,2,83,0,41,2,122,31,82,101,112,108,97,99, - 101,109,101,110,116,32,102,111,114,32,111,115,46,112,97,116, - 104,46,105,115,102,105,108,101,46,105,0,128,0,0,41,1, - 114,79,0,0,0,114,71,0,0,0,114,7,0,0,0,114, - 7,0,0,0,114,8,0,0,0,218,12,95,112,97,116,104, - 95,105,115,102,105,108,101,159,0,0,0,243,2,0,0,0, - 10,2,114,80,0,0,0,99,1,0,0,0,0,0,0,0, - 0,0,0,0,1,0,0,0,3,0,0,0,67,0,0,0, - 115,22,0,0,0,124,0,115,6,116,0,160,1,161,0,125, - 0,116,2,124,0,100,1,131,2,83,0,41,2,122,30,82, - 101,112,108,97,99,101,109,101,110,116,32,102,111,114,32,111, - 115,46,112,97,116,104,46,105,115,100,105,114,46,105,0,64, - 0,0,41,3,114,18,0,0,0,218,6,103,101,116,99,119, - 100,114,79,0,0,0,114,71,0,0,0,114,7,0,0,0, - 114,7,0,0,0,114,8,0,0,0,218,11,95,112,97,116, - 104,95,105,115,100,105,114,164,0,0,0,115,6,0,0,0, - 4,2,8,1,10,1,114,83,0,0,0,99,1,0,0,0, - 0,0,0,0,0,0,0,0,2,0,0,0,4,0,0,0, - 67,0,0,0,115,62,0,0,0,124,0,115,4,100,1,83, - 0,116,0,160,1,124,0,161,1,100,2,25,0,160,2,100, - 3,100,4,161,2,125,1,116,3,124,1,131,1,100,5,107, - 4,111,30,124,1,160,4,100,6,161,1,112,30,124,1,160, - 5,100,4,161,1,83,0,41,7,250,30,82,101,112,108,97, - 99,101,109,101,110,116,32,102,111,114,32,111,115,46,112,97, - 116,104,46,105,115,97,98,115,46,70,114,0,0,0,0,114, - 2,0,0,0,114,1,0,0,0,114,3,0,0,0,122,2, - 92,92,41,6,114,18,0,0,0,114,56,0,0,0,218,7, - 114,101,112,108,97,99,101,114,4,0,0,0,114,26,0,0, - 0,114,58,0,0,0,41,2,114,65,0,0,0,114,64,0, - 0,0,114,7,0,0,0,114,7,0,0,0,114,8,0,0, - 0,218,11,95,112,97,116,104,95,105,115,97,98,115,172,0, - 0,0,115,8,0,0,0,4,2,4,1,22,1,32,1,114, - 86,0,0,0,99,1,0,0,0,0,0,0,0,0,0,0, - 0,1,0,0,0,3,0,0,0,67,0,0,0,115,10,0, - 0,0,124,0,160,0,116,1,161,1,83,0,41,1,114,84, - 0,0,0,41,2,114,26,0,0,0,114,50,0,0,0,114, - 71,0,0,0,114,7,0,0,0,114,7,0,0,0,114,8, - 0,0,0,114,86,0,0,0,180,0,0,0,114,81,0,0, - 0,233,182,1,0,0,99,3,0,0,0,0,0,0,0,0, - 0,0,0,6,0,0,0,11,0,0,0,67,0,0,0,115, - 170,0,0,0,100,1,160,0,124,0,116,1,124,0,131,1, - 161,2,125,3,116,2,160,3,124,3,116,2,106,4,116,2, - 106,5,66,0,116,2,106,6,66,0,124,2,100,2,64,0, - 161,3,125,4,122,36,116,7,160,8,124,4,100,3,161,2, - 143,13,125,5,124,5,160,9,124,1,161,1,1,0,87,0, - 100,4,4,0,4,0,131,3,1,0,110,8,49,0,115,47, - 119,1,1,0,1,0,1,0,89,0,1,0,116,2,160,10, - 124,3,124,0,161,2,1,0,87,0,100,4,83,0,4,0, - 116,11,121,84,1,0,1,0,1,0,122,7,116,2,160,12, - 124,3,161,1,1,0,87,0,130,0,4,0,116,11,121,83, - 1,0,1,0,1,0,89,0,130,0,119,0,119,0,41,5, - 122,162,66,101,115,116,45,101,102,102,111,114,116,32,102,117, - 110,99,116,105,111,110,32,116,111,32,119,114,105,116,101,32, - 100,97,116,97,32,116,111,32,97,32,112,97,116,104,32,97, - 116,111,109,105,99,97,108,108,121,46,10,32,32,32,32,66, - 101,32,112,114,101,112,97,114,101,100,32,116,111,32,104,97, - 110,100,108,101,32,97,32,70,105,108,101,69,120,105,115,116, - 115,69,114,114,111,114,32,105,102,32,99,111,110,99,117,114, - 114,101,110,116,32,119,114,105,116,105,110,103,32,111,102,32, - 116,104,101,10,32,32,32,32,116,101,109,112,111,114,97,114, - 121,32,102,105,108,101,32,105,115,32,97,116,116,101,109,112, - 116,101,100,46,250,5,123,125,46,123,125,114,87,0,0,0, - 90,2,119,98,78,41,13,218,6,102,111,114,109,97,116,218, - 2,105,100,114,18,0,0,0,90,4,111,112,101,110,90,6, - 79,95,69,88,67,76,90,7,79,95,67,82,69,65,84,90, - 8,79,95,87,82,79,78,76,89,218,3,95,105,111,218,6, - 70,105,108,101,73,79,218,5,119,114,105,116,101,114,85,0, - 0,0,114,76,0,0,0,90,6,117,110,108,105,110,107,41, - 6,114,65,0,0,0,114,41,0,0,0,114,78,0,0,0, - 90,8,112,97,116,104,95,116,109,112,90,2,102,100,218,4, - 102,105,108,101,114,7,0,0,0,114,7,0,0,0,114,8, - 0,0,0,218,13,95,119,114,105,116,101,95,97,116,111,109, - 105,99,185,0,0,0,115,36,0,0,0,16,5,6,1,22, - 1,4,255,2,2,14,3,12,1,28,255,18,2,12,1,2, - 1,12,1,2,3,12,254,2,1,2,1,2,254,2,253,114, - 95,0,0,0,105,111,13,0,0,114,44,0,0,0,114,32, - 0,0,0,115,2,0,0,0,13,10,90,11,95,95,112,121, - 99,97,99,104,101,95,95,122,4,111,112,116,45,122,3,46, - 112,121,122,4,46,112,121,119,122,4,46,112,121,99,41,1, - 218,12,111,112,116,105,109,105,122,97,116,105,111,110,99,2, - 0,0,0,0,0,0,0,1,0,0,0,12,0,0,0,5, - 0,0,0,67,0,0,0,115,80,1,0,0,124,1,100,1, - 117,1,114,26,116,0,160,1,100,2,116,2,161,2,1,0, - 124,2,100,1,117,1,114,20,100,3,125,3,116,3,124,3, - 131,1,130,1,124,1,114,24,100,4,110,1,100,5,125,2, - 116,4,160,5,124,0,161,1,125,0,116,6,124,0,131,1, - 92,2,125,4,125,5,124,5,160,7,100,6,161,1,92,3, - 125,6,125,7,125,8,116,8,106,9,106,10,125,9,124,9, - 100,1,117,0,114,57,116,11,100,7,131,1,130,1,100,4, - 160,12,124,6,114,63,124,6,110,1,124,8,124,7,124,9, - 103,3,161,1,125,10,124,2,100,1,117,0,114,86,116,8, - 106,13,106,14,100,8,107,2,114,82,100,4,125,2,110,4, - 116,8,106,13,106,14,125,2,116,15,124,2,131,1,125,2, - 124,2,100,4,107,3,114,112,124,2,160,16,161,0,115,105, - 116,17,100,9,160,18,124,2,161,1,131,1,130,1,100,10, - 160,18,124,10,116,19,124,2,161,3,125,10,124,10,116,20, - 100,8,25,0,23,0,125,11,116,8,106,21,100,1,117,1, - 114,162,116,22,124,4,131,1,115,134,116,23,116,4,160,24, - 161,0,124,4,131,2,125,4,124,4,100,5,25,0,100,11, - 107,2,114,152,124,4,100,8,25,0,116,25,118,1,114,152, - 124,4,100,12,100,1,133,2,25,0,125,4,116,23,116,8, - 106,21,124,4,160,26,116,25,161,1,124,11,131,3,83,0, - 116,23,124,4,116,27,124,11,131,3,83,0,41,13,97,254, - 2,0,0,71,105,118,101,110,32,116,104,101,32,112,97,116, - 104,32,116,111,32,97,32,46,112,121,32,102,105,108,101,44, - 32,114,101,116,117,114,110,32,116,104,101,32,112,97,116,104, - 32,116,111,32,105,116,115,32,46,112,121,99,32,102,105,108, - 101,46,10,10,32,32,32,32,84,104,101,32,46,112,121,32, - 102,105,108,101,32,100,111,101,115,32,110,111,116,32,110,101, - 101,100,32,116,111,32,101,120,105,115,116,59,32,116,104,105, - 115,32,115,105,109,112,108,121,32,114,101,116,117,114,110,115, - 32,116,104,101,32,112,97,116,104,32,116,111,32,116,104,101, - 10,32,32,32,32,46,112,121,99,32,102,105,108,101,32,99, - 97,108,99,117,108,97,116,101,100,32,97,115,32,105,102,32, - 116,104,101,32,46,112,121,32,102,105,108,101,32,119,101,114, - 101,32,105,109,112,111,114,116,101,100,46,10,10,32,32,32, - 32,84,104,101,32,39,111,112,116,105,109,105,122,97,116,105, - 111,110,39,32,112,97,114,97,109,101,116,101,114,32,99,111, - 110,116,114,111,108,115,32,116,104,101,32,112,114,101,115,117, - 109,101,100,32,111,112,116,105,109,105,122,97,116,105,111,110, - 32,108,101,118,101,108,32,111,102,10,32,32,32,32,116,104, - 101,32,98,121,116,101,99,111,100,101,32,102,105,108,101,46, - 32,73,102,32,39,111,112,116,105,109,105,122,97,116,105,111, - 110,39,32,105,115,32,110,111,116,32,78,111,110,101,44,32, - 116,104,101,32,115,116,114,105,110,103,32,114,101,112,114,101, - 115,101,110,116,97,116,105,111,110,10,32,32,32,32,111,102, - 32,116,104,101,32,97,114,103,117,109,101,110,116,32,105,115, - 32,116,97,107,101,110,32,97,110,100,32,118,101,114,105,102, - 105,101,100,32,116,111,32,98,101,32,97,108,112,104,97,110, - 117,109,101,114,105,99,32,40,101,108,115,101,32,86,97,108, - 117,101,69,114,114,111,114,10,32,32,32,32,105,115,32,114, - 97,105,115,101,100,41,46,10,10,32,32,32,32,84,104,101, - 32,100,101,98,117,103,95,111,118,101,114,114,105,100,101,32, - 112,97,114,97,109,101,116,101,114,32,105,115,32,100,101,112, - 114,101,99,97,116,101,100,46,32,73,102,32,100,101,98,117, - 103,95,111,118,101,114,114,105,100,101,32,105,115,32,110,111, - 116,32,78,111,110,101,44,10,32,32,32,32,97,32,84,114, - 117,101,32,118,97,108,117,101,32,105,115,32,116,104,101,32, - 115,97,109,101,32,97,115,32,115,101,116,116,105,110,103,32, - 39,111,112,116,105,109,105,122,97,116,105,111,110,39,32,116, - 111,32,116,104,101,32,101,109,112,116,121,32,115,116,114,105, - 110,103,10,32,32,32,32,119,104,105,108,101,32,97,32,70, - 97,108,115,101,32,118,97,108,117,101,32,105,115,32,101,113, - 117,105,118,97,108,101,110,116,32,116,111,32,115,101,116,116, - 105,110,103,32,39,111,112,116,105,109,105,122,97,116,105,111, - 110,39,32,116,111,32,39,49,39,46,10,10,32,32,32,32, - 73,102,32,115,121,115,46,105,109,112,108,101,109,101,110,116, - 97,116,105,111,110,46,99,97,99,104,101,95,116,97,103,32, - 105,115,32,78,111,110,101,32,116,104,101,110,32,78,111,116, - 73,109,112,108,101,109,101,110,116,101,100,69,114,114,111,114, - 32,105,115,32,114,97,105,115,101,100,46,10,10,32,32,32, - 32,78,122,70,116,104,101,32,100,101,98,117,103,95,111,118, - 101,114,114,105,100,101,32,112,97,114,97,109,101,116,101,114, - 32,105,115,32,100,101,112,114,101,99,97,116,101,100,59,32, - 117,115,101,32,39,111,112,116,105,109,105,122,97,116,105,111, - 110,39,32,105,110,115,116,101,97,100,122,50,100,101,98,117, - 103,95,111,118,101,114,114,105,100,101,32,111,114,32,111,112, - 116,105,109,105,122,97,116,105,111,110,32,109,117,115,116,32, - 98,101,32,115,101,116,32,116,111,32,78,111,110,101,114,10, - 0,0,0,114,3,0,0,0,218,1,46,250,36,115,121,115, - 46,105,109,112,108,101,109,101,110,116,97,116,105,111,110,46, - 99,97,99,104,101,95,116,97,103,32,105,115,32,78,111,110, - 101,114,0,0,0,0,122,24,123,33,114,125,32,105,115,32, - 110,111,116,32,97,108,112,104,97,110,117,109,101,114,105,99, - 122,7,123,125,46,123,125,123,125,114,11,0,0,0,114,44, - 0,0,0,41,28,218,9,95,119,97,114,110,105,110,103,115, - 218,4,119,97,114,110,218,18,68,101,112,114,101,99,97,116, - 105,111,110,87,97,114,110,105,110,103,218,9,84,121,112,101, - 69,114,114,111,114,114,18,0,0,0,218,6,102,115,112,97, - 116,104,114,74,0,0,0,218,10,114,112,97,114,116,105,116, - 105,111,110,114,15,0,0,0,218,14,105,109,112,108,101,109, - 101,110,116,97,116,105,111,110,218,9,99,97,99,104,101,95, - 116,97,103,218,19,78,111,116,73,109,112,108,101,109,101,110, - 116,101,100,69,114,114,111,114,114,62,0,0,0,114,16,0, - 0,0,218,8,111,112,116,105,109,105,122,101,218,3,115,116, - 114,218,7,105,115,97,108,110,117,109,218,10,86,97,108,117, - 101,69,114,114,111,114,114,89,0,0,0,218,4,95,79,80, - 84,218,17,66,89,84,69,67,79,68,69,95,83,85,70,70, - 73,88,69,83,218,14,112,121,99,97,99,104,101,95,112,114, - 101,102,105,120,114,86,0,0,0,114,67,0,0,0,114,82, - 0,0,0,114,50,0,0,0,218,6,108,115,116,114,105,112, - 218,8,95,80,89,67,65,67,72,69,41,12,114,65,0,0, - 0,90,14,100,101,98,117,103,95,111,118,101,114,114,105,100, - 101,114,96,0,0,0,218,7,109,101,115,115,97,103,101,218, - 4,104,101,97,100,114,66,0,0,0,90,4,98,97,115,101, - 114,6,0,0,0,218,4,114,101,115,116,90,3,116,97,103, - 90,15,97,108,109,111,115,116,95,102,105,108,101,110,97,109, - 101,218,8,102,105,108,101,110,97,109,101,114,7,0,0,0, - 114,7,0,0,0,114,8,0,0,0,218,17,99,97,99,104, - 101,95,102,114,111,109,95,115,111,117,114,99,101,124,1,0, - 0,115,72,0,0,0,8,18,6,1,2,1,4,255,8,2, - 4,1,8,1,12,1,10,1,12,1,16,1,8,1,8,1, - 8,1,24,1,8,1,12,1,6,1,8,2,8,1,8,1, - 8,1,14,1,14,1,12,1,10,1,8,9,14,1,24,5, - 12,1,2,4,4,1,8,1,2,1,4,253,12,5,114,121, - 0,0,0,99,1,0,0,0,0,0,0,0,0,0,0,0, - 10,0,0,0,5,0,0,0,67,0,0,0,115,40,1,0, - 0,116,0,106,1,106,2,100,1,117,0,114,10,116,3,100, - 2,131,1,130,1,116,4,160,5,124,0,161,1,125,0,116, - 6,124,0,131,1,92,2,125,1,125,2,100,3,125,3,116, - 0,106,7,100,1,117,1,114,51,116,0,106,7,160,8,116, - 9,161,1,125,4,124,1,160,10,124,4,116,11,23,0,161, - 1,114,51,124,1,116,12,124,4,131,1,100,1,133,2,25, - 0,125,1,100,4,125,3,124,3,115,72,116,6,124,1,131, - 1,92,2,125,1,125,5,124,5,116,13,107,3,114,72,116, - 14,116,13,155,0,100,5,124,0,155,2,157,3,131,1,130, - 1,124,2,160,15,100,6,161,1,125,6,124,6,100,7,118, - 1,114,88,116,14,100,8,124,2,155,2,157,2,131,1,130, - 1,124,6,100,9,107,2,114,132,124,2,160,16,100,6,100, - 10,161,2,100,11,25,0,125,7,124,7,160,10,116,17,161, - 1,115,112,116,14,100,12,116,17,155,2,157,2,131,1,130, - 1,124,7,116,12,116,17,131,1,100,1,133,2,25,0,125, - 8,124,8,160,18,161,0,115,132,116,14,100,13,124,7,155, - 2,100,14,157,3,131,1,130,1,124,2,160,19,100,6,161, - 1,100,15,25,0,125,9,116,20,124,1,124,9,116,21,100, - 15,25,0,23,0,131,2,83,0,41,16,97,110,1,0,0, - 71,105,118,101,110,32,116,104,101,32,112,97,116,104,32,116, - 111,32,97,32,46,112,121,99,46,32,102,105,108,101,44,32, - 114,101,116,117,114,110,32,116,104,101,32,112,97,116,104,32, - 116,111,32,105,116,115,32,46,112,121,32,102,105,108,101,46, - 10,10,32,32,32,32,84,104,101,32,46,112,121,99,32,102, - 105,108,101,32,100,111,101,115,32,110,111,116,32,110,101,101, - 100,32,116,111,32,101,120,105,115,116,59,32,116,104,105,115, - 32,115,105,109,112,108,121,32,114,101,116,117,114,110,115,32, - 116,104,101,32,112,97,116,104,32,116,111,10,32,32,32,32, - 116,104,101,32,46,112,121,32,102,105,108,101,32,99,97,108, - 99,117,108,97,116,101,100,32,116,111,32,99,111,114,114,101, - 115,112,111,110,100,32,116,111,32,116,104,101,32,46,112,121, - 99,32,102,105,108,101,46,32,32,73,102,32,112,97,116,104, - 32,100,111,101,115,10,32,32,32,32,110,111,116,32,99,111, - 110,102,111,114,109,32,116,111,32,80,69,80,32,51,49,52, - 55,47,52,56,56,32,102,111,114,109,97,116,44,32,86,97, - 108,117,101,69,114,114,111,114,32,119,105,108,108,32,98,101, - 32,114,97,105,115,101,100,46,32,73,102,10,32,32,32,32, - 115,121,115,46,105,109,112,108,101,109,101,110,116,97,116,105, - 111,110,46,99,97,99,104,101,95,116,97,103,32,105,115,32, - 78,111,110,101,32,116,104,101,110,32,78,111,116,73,109,112, - 108,101,109,101,110,116,101,100,69,114,114,111,114,32,105,115, - 32,114,97,105,115,101,100,46,10,10,32,32,32,32,78,114, - 98,0,0,0,70,84,122,31,32,110,111,116,32,98,111,116, - 116,111,109,45,108,101,118,101,108,32,100,105,114,101,99,116, - 111,114,121,32,105,110,32,114,97,0,0,0,62,2,0,0, - 0,114,44,0,0,0,233,3,0,0,0,122,29,101,120,112, - 101,99,116,101,100,32,111,110,108,121,32,50,32,111,114,32, - 51,32,100,111,116,115,32,105,110,32,114,122,0,0,0,114, - 44,0,0,0,233,254,255,255,255,122,53,111,112,116,105,109, - 105,122,97,116,105,111,110,32,112,111,114,116,105,111,110,32, - 111,102,32,102,105,108,101,110,97,109,101,32,100,111,101,115, - 32,110,111,116,32,115,116,97,114,116,32,119,105,116,104,32, - 122,19,111,112,116,105,109,105,122,97,116,105,111,110,32,108, - 101,118,101,108,32,122,29,32,105,115,32,110,111,116,32,97, - 110,32,97,108,112,104,97,110,117,109,101,114,105,99,32,118, - 97,108,117,101,114,0,0,0,0,41,22,114,15,0,0,0, - 114,105,0,0,0,114,106,0,0,0,114,107,0,0,0,114, - 18,0,0,0,114,103,0,0,0,114,74,0,0,0,114,114, - 0,0,0,114,49,0,0,0,114,50,0,0,0,114,26,0, - 0,0,114,59,0,0,0,114,4,0,0,0,114,116,0,0, - 0,114,111,0,0,0,218,5,99,111,117,110,116,218,6,114, - 115,112,108,105,116,114,112,0,0,0,114,110,0,0,0,218, - 9,112,97,114,116,105,116,105,111,110,114,67,0,0,0,218, - 15,83,79,85,82,67,69,95,83,85,70,70,73,88,69,83, - 41,10,114,65,0,0,0,114,118,0,0,0,90,16,112,121, - 99,97,99,104,101,95,102,105,108,101,110,97,109,101,90,23, - 102,111,117,110,100,95,105,110,95,112,121,99,97,99,104,101, - 95,112,114,101,102,105,120,90,13,115,116,114,105,112,112,101, - 100,95,112,97,116,104,90,7,112,121,99,97,99,104,101,90, - 9,100,111,116,95,99,111,117,110,116,114,96,0,0,0,90, - 9,111,112,116,95,108,101,118,101,108,90,13,98,97,115,101, - 95,102,105,108,101,110,97,109,101,114,7,0,0,0,114,7, - 0,0,0,114,8,0,0,0,218,17,115,111,117,114,99,101, - 95,102,114,111,109,95,99,97,99,104,101,195,1,0,0,115, - 60,0,0,0,12,9,8,1,10,1,12,1,4,1,10,1, - 12,1,14,1,16,1,4,1,4,1,12,1,8,1,8,1, - 2,1,8,255,10,2,8,1,14,1,8,1,16,1,10,1, - 4,1,2,1,8,255,16,2,8,1,16,1,14,2,18,1, - 114,128,0,0,0,99,1,0,0,0,0,0,0,0,0,0, - 0,0,5,0,0,0,9,0,0,0,67,0,0,0,115,124, - 0,0,0,116,0,124,0,131,1,100,1,107,2,114,8,100, - 2,83,0,124,0,160,1,100,3,161,1,92,3,125,1,125, - 2,125,3,124,1,114,28,124,3,160,2,161,0,100,4,100, - 5,133,2,25,0,100,6,107,3,114,30,124,0,83,0,122, - 6,116,3,124,0,131,1,125,4,87,0,110,17,4,0,116, - 4,116,5,102,2,121,53,1,0,1,0,1,0,124,0,100, - 2,100,5,133,2,25,0,125,4,89,0,110,1,119,0,116, - 6,124,4,131,1,114,60,124,4,83,0,124,0,83,0,41, - 7,122,188,67,111,110,118,101,114,116,32,97,32,98,121,116, - 101,99,111,100,101,32,102,105,108,101,32,112,97,116,104,32, - 116,111,32,97,32,115,111,117,114,99,101,32,112,97,116,104, - 32,40,105,102,32,112,111,115,115,105,98,108,101,41,46,10, - 10,32,32,32,32,84,104,105,115,32,102,117,110,99,116,105, - 111,110,32,101,120,105,115,116,115,32,112,117,114,101,108,121, - 32,102,111,114,32,98,97,99,107,119,97,114,100,115,45,99, - 111,109,112,97,116,105,98,105,108,105,116,121,32,102,111,114, - 10,32,32,32,32,80,121,73,109,112,111,114,116,95,69,120, - 101,99,67,111,100,101,77,111,100,117,108,101,87,105,116,104, - 70,105,108,101,110,97,109,101,115,40,41,32,105,110,32,116, - 104,101,32,67,32,65,80,73,46,10,10,32,32,32,32,114, - 0,0,0,0,78,114,97,0,0,0,233,253,255,255,255,233, - 255,255,255,255,90,2,112,121,41,7,114,4,0,0,0,114, - 104,0,0,0,218,5,108,111,119,101,114,114,128,0,0,0, - 114,107,0,0,0,114,111,0,0,0,114,80,0,0,0,41, - 5,218,13,98,121,116,101,99,111,100,101,95,112,97,116,104, - 114,119,0,0,0,218,1,95,90,9,101,120,116,101,110,115, - 105,111,110,218,11,115,111,117,114,99,101,95,112,97,116,104, - 114,7,0,0,0,114,7,0,0,0,114,8,0,0,0,218, - 15,95,103,101,116,95,115,111,117,114,99,101,102,105,108,101, - 235,1,0,0,115,22,0,0,0,12,7,4,1,16,1,24, - 1,4,1,2,1,12,1,16,1,16,1,2,255,16,2,114, - 135,0,0,0,99,1,0,0,0,0,0,0,0,0,0,0, - 0,1,0,0,0,8,0,0,0,67,0,0,0,115,68,0, - 0,0,124,0,160,0,116,1,116,2,131,1,161,1,114,23, - 122,5,116,3,124,0,131,1,87,0,83,0,4,0,116,4, - 121,22,1,0,1,0,1,0,89,0,100,0,83,0,119,0, - 124,0,160,0,116,1,116,5,131,1,161,1,114,32,124,0, - 83,0,100,0,83,0,114,69,0,0,0,41,6,114,58,0, - 0,0,218,5,116,117,112,108,101,114,127,0,0,0,114,121, - 0,0,0,114,107,0,0,0,114,113,0,0,0,41,1,114, - 120,0,0,0,114,7,0,0,0,114,7,0,0,0,114,8, - 0,0,0,218,11,95,103,101,116,95,99,97,99,104,101,100, - 254,1,0,0,115,18,0,0,0,14,1,2,1,10,1,12, - 1,6,1,2,255,14,2,4,1,4,2,114,137,0,0,0, - 99,1,0,0,0,0,0,0,0,0,0,0,0,2,0,0, - 0,8,0,0,0,67,0,0,0,115,50,0,0,0,122,7, - 116,0,124,0,131,1,106,1,125,1,87,0,110,11,4,0, - 116,2,121,18,1,0,1,0,1,0,100,1,125,1,89,0, - 110,1,119,0,124,1,100,2,79,0,125,1,124,1,83,0, - 41,3,122,51,67,97,108,99,117,108,97,116,101,32,116,104, - 101,32,109,111,100,101,32,112,101,114,109,105,115,115,105,111, - 110,115,32,102,111,114,32,97,32,98,121,116,101,99,111,100, - 101,32,102,105,108,101,46,114,87,0,0,0,233,128,0,0, - 0,41,3,114,75,0,0,0,114,77,0,0,0,114,76,0, - 0,0,41,2,114,65,0,0,0,114,78,0,0,0,114,7, - 0,0,0,114,7,0,0,0,114,8,0,0,0,218,10,95, - 99,97,108,99,95,109,111,100,101,10,2,0,0,115,14,0, - 0,0,2,2,14,1,12,1,8,1,2,255,8,4,4,1, - 114,139,0,0,0,99,1,0,0,0,0,0,0,0,0,0, - 0,0,3,0,0,0,4,0,0,0,3,0,0,0,115,52, - 0,0,0,100,6,135,0,102,1,100,2,100,3,132,9,125, - 1,116,0,100,1,117,1,114,15,116,0,106,1,125,2,110, - 4,100,4,100,5,132,0,125,2,124,2,124,1,136,0,131, - 2,1,0,124,1,83,0,41,7,122,252,68,101,99,111,114, - 97,116,111,114,32,116,111,32,118,101,114,105,102,121,32,116, - 104,97,116,32,116,104,101,32,109,111,100,117,108,101,32,98, - 101,105,110,103,32,114,101,113,117,101,115,116,101,100,32,109, - 97,116,99,104,101,115,32,116,104,101,32,111,110,101,32,116, - 104,101,10,32,32,32,32,108,111,97,100,101,114,32,99,97, - 110,32,104,97,110,100,108,101,46,10,10,32,32,32,32,84, - 104,101,32,102,105,114,115,116,32,97,114,103,117,109,101,110, - 116,32,40,115,101,108,102,41,32,109,117,115,116,32,100,101, - 102,105,110,101,32,95,110,97,109,101,32,119,104,105,99,104, - 32,116,104,101,32,115,101,99,111,110,100,32,97,114,103,117, - 109,101,110,116,32,105,115,10,32,32,32,32,99,111,109,112, - 97,114,101,100,32,97,103,97,105,110,115,116,46,32,73,102, - 32,116,104,101,32,99,111,109,112,97,114,105,115,111,110,32, - 102,97,105,108,115,32,116,104,101,110,32,73,109,112,111,114, - 116,69,114,114,111,114,32,105,115,32,114,97,105,115,101,100, - 46,10,10,32,32,32,32,78,99,2,0,0,0,0,0,0, - 0,0,0,0,0,4,0,0,0,4,0,0,0,31,0,0, - 0,115,72,0,0,0,124,1,100,0,117,0,114,8,124,0, - 106,0,125,1,110,16,124,0,106,0,124,1,107,3,114,24, - 116,1,100,1,124,0,106,0,124,1,102,2,22,0,124,1, - 100,2,141,2,130,1,136,0,124,0,124,1,103,2,124,2, - 162,1,82,0,105,0,124,3,164,1,142,1,83,0,41,3, - 78,122,30,108,111,97,100,101,114,32,102,111,114,32,37,115, - 32,99,97,110,110,111,116,32,104,97,110,100,108,101,32,37, - 115,169,1,218,4,110,97,109,101,41,2,114,141,0,0,0, - 218,11,73,109,112,111,114,116,69,114,114,111,114,41,4,218, - 4,115,101,108,102,114,141,0,0,0,218,4,97,114,103,115, - 218,6,107,119,97,114,103,115,169,1,218,6,109,101,116,104, - 111,100,114,7,0,0,0,114,8,0,0,0,218,19,95,99, - 104,101,99,107,95,110,97,109,101,95,119,114,97,112,112,101, - 114,30,2,0,0,115,18,0,0,0,8,1,8,1,10,1, - 4,1,8,1,2,255,2,1,6,255,24,2,122,40,95,99, - 104,101,99,107,95,110,97,109,101,46,60,108,111,99,97,108, - 115,62,46,95,99,104,101,99,107,95,110,97,109,101,95,119, - 114,97,112,112,101,114,99,2,0,0,0,0,0,0,0,0, - 0,0,0,3,0,0,0,7,0,0,0,83,0,0,0,115, - 56,0,0,0,100,1,68,0,93,16,125,2,116,0,124,1, - 124,2,131,2,114,18,116,1,124,0,124,2,116,2,124,1, - 124,2,131,2,131,3,1,0,113,2,124,0,106,3,160,4, - 124,1,106,3,161,1,1,0,100,0,83,0,41,2,78,41, - 4,218,10,95,95,109,111,100,117,108,101,95,95,218,8,95, - 95,110,97,109,101,95,95,218,12,95,95,113,117,97,108,110, - 97,109,101,95,95,218,7,95,95,100,111,99,95,95,41,5, - 218,7,104,97,115,97,116,116,114,218,7,115,101,116,97,116, - 116,114,218,7,103,101,116,97,116,116,114,218,8,95,95,100, - 105,99,116,95,95,218,6,117,112,100,97,116,101,41,3,90, - 3,110,101,119,90,3,111,108,100,114,85,0,0,0,114,7, - 0,0,0,114,7,0,0,0,114,8,0,0,0,218,5,95, - 119,114,97,112,43,2,0,0,115,10,0,0,0,8,1,10, - 1,18,1,2,128,18,1,122,26,95,99,104,101,99,107,95, - 110,97,109,101,46,60,108,111,99,97,108,115,62,46,95,119, - 114,97,112,114,69,0,0,0,41,2,218,10,95,98,111,111, - 116,115,116,114,97,112,114,158,0,0,0,41,3,114,147,0, - 0,0,114,148,0,0,0,114,158,0,0,0,114,7,0,0, - 0,114,146,0,0,0,114,8,0,0,0,218,11,95,99,104, - 101,99,107,95,110,97,109,101,22,2,0,0,115,12,0,0, - 0,14,8,8,10,8,1,8,2,10,6,4,1,114,160,0, - 0,0,99,2,0,0,0,0,0,0,0,0,0,0,0,5, - 0,0,0,6,0,0,0,67,0,0,0,115,72,0,0,0, - 116,0,160,1,100,1,116,2,161,2,1,0,124,0,160,3, - 124,1,161,1,92,2,125,2,125,3,124,2,100,2,117,0, - 114,34,116,4,124,3,131,1,114,34,100,3,125,4,116,0, - 160,1,124,4,160,5,124,3,100,4,25,0,161,1,116,6, - 161,2,1,0,124,2,83,0,41,5,122,155,84,114,121,32, - 116,111,32,102,105,110,100,32,97,32,108,111,97,100,101,114, - 32,102,111,114,32,116,104,101,32,115,112,101,99,105,102,105, - 101,100,32,109,111,100,117,108,101,32,98,121,32,100,101,108, - 101,103,97,116,105,110,103,32,116,111,10,32,32,32,32,115, - 101,108,102,46,102,105,110,100,95,108,111,97,100,101,114,40, - 41,46,10,10,32,32,32,32,84,104,105,115,32,109,101,116, - 104,111,100,32,105,115,32,100,101,112,114,101,99,97,116,101, - 100,32,105,110,32,102,97,118,111,114,32,111,102,32,102,105, - 110,100,101,114,46,102,105,110,100,95,115,112,101,99,40,41, - 46,10,10,32,32,32,32,122,90,102,105,110,100,95,109,111, - 100,117,108,101,40,41,32,105,115,32,100,101,112,114,101,99, - 97,116,101,100,32,97,110,100,32,115,108,97,116,101,100,32, - 102,111,114,32,114,101,109,111,118,97,108,32,105,110,32,80, - 121,116,104,111,110,32,51,46,49,50,59,32,117,115,101,32, - 102,105,110,100,95,115,112,101,99,40,41,32,105,110,115,116, - 101,97,100,78,122,44,78,111,116,32,105,109,112,111,114,116, - 105,110,103,32,100,105,114,101,99,116,111,114,121,32,123,125, - 58,32,109,105,115,115,105,110,103,32,95,95,105,110,105,116, - 95,95,114,0,0,0,0,41,7,114,99,0,0,0,114,100, - 0,0,0,114,101,0,0,0,218,11,102,105,110,100,95,108, - 111,97,100,101,114,114,4,0,0,0,114,89,0,0,0,218, - 13,73,109,112,111,114,116,87,97,114,110,105,110,103,41,5, - 114,143,0,0,0,218,8,102,117,108,108,110,97,109,101,218, - 6,108,111,97,100,101,114,218,8,112,111,114,116,105,111,110, - 115,218,3,109,115,103,114,7,0,0,0,114,7,0,0,0, - 114,8,0,0,0,218,17,95,102,105,110,100,95,109,111,100, - 117,108,101,95,115,104,105,109,53,2,0,0,115,16,0,0, - 0,6,7,2,2,4,254,14,6,16,1,4,1,22,1,4, - 1,114,167,0,0,0,99,3,0,0,0,0,0,0,0,0, - 0,0,0,6,0,0,0,4,0,0,0,67,0,0,0,115, - 166,0,0,0,124,0,100,1,100,2,133,2,25,0,125,3, - 124,3,116,0,107,3,114,32,100,3,124,1,155,2,100,4, - 124,3,155,2,157,4,125,4,116,1,160,2,100,5,124,4, - 161,2,1,0,116,3,124,4,102,1,105,0,124,2,164,1, - 142,1,130,1,116,4,124,0,131,1,100,6,107,0,114,53, - 100,7,124,1,155,2,157,2,125,4,116,1,160,2,100,5, - 124,4,161,2,1,0,116,5,124,4,131,1,130,1,116,6, - 124,0,100,2,100,8,133,2,25,0,131,1,125,5,124,5, - 100,9,64,0,114,81,100,10,124,5,155,2,100,11,124,1, - 155,2,157,4,125,4,116,3,124,4,102,1,105,0,124,2, - 164,1,142,1,130,1,124,5,83,0,41,12,97,84,2,0, - 0,80,101,114,102,111,114,109,32,98,97,115,105,99,32,118, - 97,108,105,100,105,116,121,32,99,104,101,99,107,105,110,103, - 32,111,102,32,97,32,112,121,99,32,104,101,97,100,101,114, - 32,97,110,100,32,114,101,116,117,114,110,32,116,104,101,32, - 102,108,97,103,115,32,102,105,101,108,100,44,10,32,32,32, - 32,119,104,105,99,104,32,100,101,116,101,114,109,105,110,101, - 115,32,104,111,119,32,116,104,101,32,112,121,99,32,115,104, - 111,117,108,100,32,98,101,32,102,117,114,116,104,101,114,32, - 118,97,108,105,100,97,116,101,100,32,97,103,97,105,110,115, - 116,32,116,104,101,32,115,111,117,114,99,101,46,10,10,32, - 32,32,32,42,100,97,116,97,42,32,105,115,32,116,104,101, - 32,99,111,110,116,101,110,116,115,32,111,102,32,116,104,101, - 32,112,121,99,32,102,105,108,101,46,32,40,79,110,108,121, - 32,116,104,101,32,102,105,114,115,116,32,49,54,32,98,121, - 116,101,115,32,97,114,101,10,32,32,32,32,114,101,113,117, - 105,114,101,100,44,32,116,104,111,117,103,104,46,41,10,10, - 32,32,32,32,42,110,97,109,101,42,32,105,115,32,116,104, - 101,32,110,97,109,101,32,111,102,32,116,104,101,32,109,111, - 100,117,108,101,32,98,101,105,110,103,32,105,109,112,111,114, - 116,101,100,46,32,73,116,32,105,115,32,117,115,101,100,32, - 102,111,114,32,108,111,103,103,105,110,103,46,10,10,32,32, - 32,32,42,101,120,99,95,100,101,116,97,105,108,115,42,32, - 105,115,32,97,32,100,105,99,116,105,111,110,97,114,121,32, - 112,97,115,115,101,100,32,116,111,32,73,109,112,111,114,116, - 69,114,114,111,114,32,105,102,32,105,116,32,114,97,105,115, - 101,100,32,102,111,114,10,32,32,32,32,105,109,112,114,111, - 118,101,100,32,100,101,98,117,103,103,105,110,103,46,10,10, - 32,32,32,32,73,109,112,111,114,116,69,114,114,111,114,32, - 105,115,32,114,97,105,115,101,100,32,119,104,101,110,32,116, - 104,101,32,109,97,103,105,99,32,110,117,109,98,101,114,32, - 105,115,32,105,110,99,111,114,114,101,99,116,32,111,114,32, - 119,104,101,110,32,116,104,101,32,102,108,97,103,115,10,32, - 32,32,32,102,105,101,108,100,32,105,115,32,105,110,118,97, - 108,105,100,46,32,69,79,70,69,114,114,111,114,32,105,115, - 32,114,97,105,115,101,100,32,119,104,101,110,32,116,104,101, - 32,100,97,116,97,32,105,115,32,102,111,117,110,100,32,116, - 111,32,98,101,32,116,114,117,110,99,97,116,101,100,46,10, - 10,32,32,32,32,78,114,31,0,0,0,122,20,98,97,100, - 32,109,97,103,105,99,32,110,117,109,98,101,114,32,105,110, - 32,122,2,58,32,250,2,123,125,233,16,0,0,0,122,40, - 114,101,97,99,104,101,100,32,69,79,70,32,119,104,105,108, - 101,32,114,101,97,100,105,110,103,32,112,121,99,32,104,101, - 97,100,101,114,32,111,102,32,233,8,0,0,0,233,252,255, - 255,255,122,14,105,110,118,97,108,105,100,32,102,108,97,103, - 115,32,122,4,32,105,110,32,41,7,218,12,77,65,71,73, - 67,95,78,85,77,66,69,82,114,159,0,0,0,218,16,95, - 118,101,114,98,111,115,101,95,109,101,115,115,97,103,101,114, - 142,0,0,0,114,4,0,0,0,218,8,69,79,70,69,114, - 114,111,114,114,42,0,0,0,41,6,114,41,0,0,0,114, - 141,0,0,0,218,11,101,120,99,95,100,101,116,97,105,108, - 115,90,5,109,97,103,105,99,114,117,0,0,0,114,16,0, - 0,0,114,7,0,0,0,114,7,0,0,0,114,8,0,0, - 0,218,13,95,99,108,97,115,115,105,102,121,95,112,121,99, - 73,2,0,0,115,28,0,0,0,12,16,8,1,16,1,12, - 1,16,1,12,1,10,1,12,1,8,1,16,1,8,2,16, - 1,16,1,4,1,114,176,0,0,0,99,5,0,0,0,0, - 0,0,0,0,0,0,0,6,0,0,0,4,0,0,0,67, - 0,0,0,115,124,0,0,0,116,0,124,0,100,1,100,2, - 133,2,25,0,131,1,124,1,100,3,64,0,107,3,114,31, - 100,4,124,3,155,2,157,2,125,5,116,1,160,2,100,5, - 124,5,161,2,1,0,116,3,124,5,102,1,105,0,124,4, - 164,1,142,1,130,1,124,2,100,6,117,1,114,58,116,0, - 124,0,100,2,100,7,133,2,25,0,131,1,124,2,100,3, - 64,0,107,3,114,60,116,3,100,4,124,3,155,2,157,2, - 102,1,105,0,124,4,164,1,142,1,130,1,100,6,83,0, - 100,6,83,0,41,8,97,7,2,0,0,86,97,108,105,100, - 97,116,101,32,97,32,112,121,99,32,97,103,97,105,110,115, - 116,32,116,104,101,32,115,111,117,114,99,101,32,108,97,115, - 116,45,109,111,100,105,102,105,101,100,32,116,105,109,101,46, - 10,10,32,32,32,32,42,100,97,116,97,42,32,105,115,32, - 116,104,101,32,99,111,110,116,101,110,116,115,32,111,102,32, - 116,104,101,32,112,121,99,32,102,105,108,101,46,32,40,79, - 110,108,121,32,116,104,101,32,102,105,114,115,116,32,49,54, - 32,98,121,116,101,115,32,97,114,101,10,32,32,32,32,114, - 101,113,117,105,114,101,100,46,41,10,10,32,32,32,32,42, - 115,111,117,114,99,101,95,109,116,105,109,101,42,32,105,115, - 32,116,104,101,32,108,97,115,116,32,109,111,100,105,102,105, - 101,100,32,116,105,109,101,115,116,97,109,112,32,111,102,32, - 116,104,101,32,115,111,117,114,99,101,32,102,105,108,101,46, - 10,10,32,32,32,32,42,115,111,117,114,99,101,95,115,105, - 122,101,42,32,105,115,32,78,111,110,101,32,111,114,32,116, - 104,101,32,115,105,122,101,32,111,102,32,116,104,101,32,115, - 111,117,114,99,101,32,102,105,108,101,32,105,110,32,98,121, - 116,101,115,46,10,10,32,32,32,32,42,110,97,109,101,42, - 32,105,115,32,116,104,101,32,110,97,109,101,32,111,102,32, - 116,104,101,32,109,111,100,117,108,101,32,98,101,105,110,103, - 32,105,109,112,111,114,116,101,100,46,32,73,116,32,105,115, - 32,117,115,101,100,32,102,111,114,32,108,111,103,103,105,110, - 103,46,10,10,32,32,32,32,42,101,120,99,95,100,101,116, - 97,105,108,115,42,32,105,115,32,97,32,100,105,99,116,105, - 111,110,97,114,121,32,112,97,115,115,101,100,32,116,111,32, - 73,109,112,111,114,116,69,114,114,111,114,32,105,102,32,105, - 116,32,114,97,105,115,101,100,32,102,111,114,10,32,32,32, - 32,105,109,112,114,111,118,101,100,32,100,101,98,117,103,103, - 105,110,103,46,10,10,32,32,32,32,65,110,32,73,109,112, - 111,114,116,69,114,114,111,114,32,105,115,32,114,97,105,115, - 101,100,32,105,102,32,116,104,101,32,98,121,116,101,99,111, - 100,101,32,105,115,32,115,116,97,108,101,46,10,10,32,32, - 32,32,114,170,0,0,0,233,12,0,0,0,114,30,0,0, - 0,122,22,98,121,116,101,99,111,100,101,32,105,115,32,115, - 116,97,108,101,32,102,111,114,32,114,168,0,0,0,78,114, - 169,0,0,0,41,4,114,42,0,0,0,114,159,0,0,0, - 114,173,0,0,0,114,142,0,0,0,41,6,114,41,0,0, - 0,218,12,115,111,117,114,99,101,95,109,116,105,109,101,218, - 11,115,111,117,114,99,101,95,115,105,122,101,114,141,0,0, - 0,114,175,0,0,0,114,117,0,0,0,114,7,0,0,0, - 114,7,0,0,0,114,8,0,0,0,218,23,95,118,97,108, - 105,100,97,116,101,95,116,105,109,101,115,116,97,109,112,95, - 112,121,99,106,2,0,0,115,18,0,0,0,24,19,10,1, - 12,1,16,1,8,1,22,1,2,255,22,2,8,254,114,180, - 0,0,0,99,4,0,0,0,0,0,0,0,0,0,0,0, - 4,0,0,0,4,0,0,0,67,0,0,0,115,42,0,0, - 0,124,0,100,1,100,2,133,2,25,0,124,1,107,3,114, - 19,116,0,100,3,124,2,155,2,157,2,102,1,105,0,124, - 3,164,1,142,1,130,1,100,4,83,0,41,5,97,243,1, - 0,0,86,97,108,105,100,97,116,101,32,97,32,104,97,115, - 104,45,98,97,115,101,100,32,112,121,99,32,98,121,32,99, - 104,101,99,107,105,110,103,32,116,104,101,32,114,101,97,108, - 32,115,111,117,114,99,101,32,104,97,115,104,32,97,103,97, - 105,110,115,116,32,116,104,101,32,111,110,101,32,105,110,10, - 32,32,32,32,116,104,101,32,112,121,99,32,104,101,97,100, - 101,114,46,10,10,32,32,32,32,42,100,97,116,97,42,32, - 105,115,32,116,104,101,32,99,111,110,116,101,110,116,115,32, - 111,102,32,116,104,101,32,112,121,99,32,102,105,108,101,46, - 32,40,79,110,108,121,32,116,104,101,32,102,105,114,115,116, - 32,49,54,32,98,121,116,101,115,32,97,114,101,10,32,32, - 32,32,114,101,113,117,105,114,101,100,46,41,10,10,32,32, - 32,32,42,115,111,117,114,99,101,95,104,97,115,104,42,32, - 105,115,32,116,104,101,32,105,109,112,111,114,116,108,105,98, - 46,117,116,105,108,46,115,111,117,114,99,101,95,104,97,115, - 104,40,41,32,111,102,32,116,104,101,32,115,111,117,114,99, - 101,32,102,105,108,101,46,10,10,32,32,32,32,42,110,97, - 109,101,42,32,105,115,32,116,104,101,32,110,97,109,101,32, - 111,102,32,116,104,101,32,109,111,100,117,108,101,32,98,101, - 105,110,103,32,105,109,112,111,114,116,101,100,46,32,73,116, - 32,105,115,32,117,115,101,100,32,102,111,114,32,108,111,103, - 103,105,110,103,46,10,10,32,32,32,32,42,101,120,99,95, - 100,101,116,97,105,108,115,42,32,105,115,32,97,32,100,105, - 99,116,105,111,110,97,114,121,32,112,97,115,115,101,100,32, - 116,111,32,73,109,112,111,114,116,69,114,114,111,114,32,105, - 102,32,105,116,32,114,97,105,115,101,100,32,102,111,114,10, - 32,32,32,32,105,109,112,114,111,118,101,100,32,100,101,98, - 117,103,103,105,110,103,46,10,10,32,32,32,32,65,110,32, - 73,109,112,111,114,116,69,114,114,111,114,32,105,115,32,114, - 97,105,115,101,100,32,105,102,32,116,104,101,32,98,121,116, - 101,99,111,100,101,32,105,115,32,115,116,97,108,101,46,10, - 10,32,32,32,32,114,170,0,0,0,114,169,0,0,0,122, - 46,104,97,115,104,32,105,110,32,98,121,116,101,99,111,100, - 101,32,100,111,101,115,110,39,116,32,109,97,116,99,104,32, - 104,97,115,104,32,111,102,32,115,111,117,114,99,101,32,78, - 41,1,114,142,0,0,0,41,4,114,41,0,0,0,218,11, - 115,111,117,114,99,101,95,104,97,115,104,114,141,0,0,0, - 114,175,0,0,0,114,7,0,0,0,114,7,0,0,0,114, - 8,0,0,0,218,18,95,118,97,108,105,100,97,116,101,95, - 104,97,115,104,95,112,121,99,134,2,0,0,115,14,0,0, - 0,16,17,2,1,8,1,4,255,2,2,6,254,4,255,114, - 182,0,0,0,99,4,0,0,0,0,0,0,0,0,0,0, - 0,5,0,0,0,5,0,0,0,67,0,0,0,115,76,0, - 0,0,116,0,160,1,124,0,161,1,125,4,116,2,124,4, - 116,3,131,2,114,28,116,4,160,5,100,1,124,2,161,2, - 1,0,124,3,100,2,117,1,114,26,116,6,160,7,124,4, - 124,3,161,2,1,0,124,4,83,0,116,8,100,3,160,9, - 124,2,161,1,124,1,124,2,100,4,141,3,130,1,41,5, - 122,35,67,111,109,112,105,108,101,32,98,121,116,101,99,111, - 100,101,32,97,115,32,102,111,117,110,100,32,105,110,32,97, - 32,112,121,99,46,122,21,99,111,100,101,32,111,98,106,101, - 99,116,32,102,114,111,109,32,123,33,114,125,78,122,23,78, - 111,110,45,99,111,100,101,32,111,98,106,101,99,116,32,105, - 110,32,123,33,114,125,169,2,114,141,0,0,0,114,65,0, - 0,0,41,10,218,7,109,97,114,115,104,97,108,90,5,108, - 111,97,100,115,218,10,105,115,105,110,115,116,97,110,99,101, - 218,10,95,99,111,100,101,95,116,121,112,101,114,159,0,0, - 0,114,173,0,0,0,218,4,95,105,109,112,90,16,95,102, - 105,120,95,99,111,95,102,105,108,101,110,97,109,101,114,142, - 0,0,0,114,89,0,0,0,41,5,114,41,0,0,0,114, - 141,0,0,0,114,132,0,0,0,114,134,0,0,0,218,4, - 99,111,100,101,114,7,0,0,0,114,7,0,0,0,114,8, - 0,0,0,218,17,95,99,111,109,112,105,108,101,95,98,121, - 116,101,99,111,100,101,158,2,0,0,115,18,0,0,0,10, - 2,10,1,12,1,8,1,12,1,4,1,10,2,4,1,6, - 255,114,189,0,0,0,99,3,0,0,0,0,0,0,0,0, - 0,0,0,4,0,0,0,5,0,0,0,67,0,0,0,115, - 70,0,0,0,116,0,116,1,131,1,125,3,124,3,160,2, - 116,3,100,1,131,1,161,1,1,0,124,3,160,2,116,3, - 124,1,131,1,161,1,1,0,124,3,160,2,116,3,124,2, - 131,1,161,1,1,0,124,3,160,2,116,4,160,5,124,0, - 161,1,161,1,1,0,124,3,83,0,41,2,122,43,80,114, - 111,100,117,99,101,32,116,104,101,32,100,97,116,97,32,102, - 111,114,32,97,32,116,105,109,101,115,116,97,109,112,45,98, - 97,115,101,100,32,112,121,99,46,114,0,0,0,0,41,6, - 218,9,98,121,116,101,97,114,114,97,121,114,172,0,0,0, - 218,6,101,120,116,101,110,100,114,36,0,0,0,114,184,0, - 0,0,218,5,100,117,109,112,115,41,4,114,188,0,0,0, - 218,5,109,116,105,109,101,114,179,0,0,0,114,41,0,0, - 0,114,7,0,0,0,114,7,0,0,0,114,8,0,0,0, - 218,22,95,99,111,100,101,95,116,111,95,116,105,109,101,115, - 116,97,109,112,95,112,121,99,171,2,0,0,115,12,0,0, - 0,8,2,14,1,14,1,14,1,16,1,4,1,114,194,0, - 0,0,84,99,3,0,0,0,0,0,0,0,0,0,0,0, - 5,0,0,0,5,0,0,0,67,0,0,0,115,80,0,0, - 0,116,0,116,1,131,1,125,3,100,1,124,2,100,1,62, - 0,66,0,125,4,124,3,160,2,116,3,124,4,131,1,161, - 1,1,0,116,4,124,1,131,1,100,2,107,2,115,25,74, - 0,130,1,124,3,160,2,124,1,161,1,1,0,124,3,160, - 2,116,5,160,6,124,0,161,1,161,1,1,0,124,3,83, - 0,41,3,122,38,80,114,111,100,117,99,101,32,116,104,101, - 32,100,97,116,97,32,102,111,114,32,97,32,104,97,115,104, - 45,98,97,115,101,100,32,112,121,99,46,114,3,0,0,0, - 114,170,0,0,0,41,7,114,190,0,0,0,114,172,0,0, - 0,114,191,0,0,0,114,36,0,0,0,114,4,0,0,0, - 114,184,0,0,0,114,192,0,0,0,41,5,114,188,0,0, - 0,114,181,0,0,0,90,7,99,104,101,99,107,101,100,114, - 41,0,0,0,114,16,0,0,0,114,7,0,0,0,114,7, - 0,0,0,114,8,0,0,0,218,17,95,99,111,100,101,95, - 116,111,95,104,97,115,104,95,112,121,99,181,2,0,0,115, - 14,0,0,0,8,2,12,1,14,1,16,1,10,1,16,1, - 4,1,114,195,0,0,0,99,1,0,0,0,0,0,0,0, - 0,0,0,0,5,0,0,0,6,0,0,0,67,0,0,0, - 115,62,0,0,0,100,1,100,2,108,0,125,1,116,1,160, - 2,124,0,161,1,106,3,125,2,124,1,160,4,124,2,161, - 1,125,3,116,1,160,5,100,2,100,3,161,2,125,4,124, - 4,160,6,124,0,160,6,124,3,100,1,25,0,161,1,161, - 1,83,0,41,4,122,121,68,101,99,111,100,101,32,98,121, - 116,101,115,32,114,101,112,114,101,115,101,110,116,105,110,103, - 32,115,111,117,114,99,101,32,99,111,100,101,32,97,110,100, - 32,114,101,116,117,114,110,32,116,104,101,32,115,116,114,105, - 110,103,46,10,10,32,32,32,32,85,110,105,118,101,114,115, - 97,108,32,110,101,119,108,105,110,101,32,115,117,112,112,111, - 114,116,32,105,115,32,117,115,101,100,32,105,110,32,116,104, - 101,32,100,101,99,111,100,105,110,103,46,10,32,32,32,32, - 114,0,0,0,0,78,84,41,7,218,8,116,111,107,101,110, - 105,122,101,114,91,0,0,0,90,7,66,121,116,101,115,73, - 79,90,8,114,101,97,100,108,105,110,101,90,15,100,101,116, - 101,99,116,95,101,110,99,111,100,105,110,103,90,25,73,110, - 99,114,101,109,101,110,116,97,108,78,101,119,108,105,110,101, - 68,101,99,111,100,101,114,218,6,100,101,99,111,100,101,41, - 5,218,12,115,111,117,114,99,101,95,98,121,116,101,115,114, - 196,0,0,0,90,21,115,111,117,114,99,101,95,98,121,116, - 101,115,95,114,101,97,100,108,105,110,101,218,8,101,110,99, - 111,100,105,110,103,90,15,110,101,119,108,105,110,101,95,100, - 101,99,111,100,101,114,114,7,0,0,0,114,7,0,0,0, - 114,8,0,0,0,218,13,100,101,99,111,100,101,95,115,111, - 117,114,99,101,192,2,0,0,115,10,0,0,0,8,5,12, - 1,10,1,12,1,20,1,114,200,0,0,0,169,2,114,164, - 0,0,0,218,26,115,117,98,109,111,100,117,108,101,95,115, - 101,97,114,99,104,95,108,111,99,97,116,105,111,110,115,99, - 2,0,0,0,0,0,0,0,2,0,0,0,9,0,0,0, - 8,0,0,0,67,0,0,0,115,54,1,0,0,124,1,100, - 1,117,0,114,29,100,2,125,1,116,0,124,2,100,3,131, - 2,114,28,122,7,124,2,160,1,124,0,161,1,125,1,87, - 0,110,38,4,0,116,2,121,27,1,0,1,0,1,0,89, - 0,110,30,119,0,110,28,116,3,160,4,124,1,161,1,125, - 1,116,5,124,1,131,1,115,57,122,9,116,6,116,3,160, - 7,161,0,124,1,131,2,125,1,87,0,110,9,4,0,116, - 8,121,56,1,0,1,0,1,0,89,0,110,1,119,0,116, - 9,106,10,124,0,124,2,124,1,100,4,141,3,125,4,100, - 5,124,4,95,11,124,2,100,1,117,0,114,99,116,12,131, - 0,68,0,93,21,92,2,125,5,125,6,124,1,160,13,116, - 14,124,6,131,1,161,1,114,96,124,5,124,0,124,1,131, - 2,125,2,124,2,124,4,95,15,1,0,110,3,113,75,100, - 1,83,0,124,3,116,16,117,0,114,131,116,0,124,2,100, - 6,131,2,114,130,122,7,124,2,160,17,124,0,161,1,125, - 7,87,0,110,9,4,0,116,2,121,124,1,0,1,0,1, - 0,89,0,110,10,119,0,124,7,114,130,103,0,124,4,95, - 18,110,3,124,3,124,4,95,18,124,4,106,18,103,0,107, - 2,114,153,124,1,114,153,116,19,124,1,131,1,100,7,25, - 0,125,8,124,4,106,18,160,20,124,8,161,1,1,0,124, - 4,83,0,41,8,97,61,1,0,0,82,101,116,117,114,110, - 32,97,32,109,111,100,117,108,101,32,115,112,101,99,32,98, - 97,115,101,100,32,111,110,32,97,32,102,105,108,101,32,108, - 111,99,97,116,105,111,110,46,10,10,32,32,32,32,84,111, - 32,105,110,100,105,99,97,116,101,32,116,104,97,116,32,116, - 104,101,32,109,111,100,117,108,101,32,105,115,32,97,32,112, - 97,99,107,97,103,101,44,32,115,101,116,10,32,32,32,32, - 115,117,98,109,111,100,117,108,101,95,115,101,97,114,99,104, - 95,108,111,99,97,116,105,111,110,115,32,116,111,32,97,32, - 108,105,115,116,32,111,102,32,100,105,114,101,99,116,111,114, - 121,32,112,97,116,104,115,46,32,32,65,110,10,32,32,32, - 32,101,109,112,116,121,32,108,105,115,116,32,105,115,32,115, - 117,102,102,105,99,105,101,110,116,44,32,116,104,111,117,103, - 104,32,105,116,115,32,110,111,116,32,111,116,104,101,114,119, - 105,115,101,32,117,115,101,102,117,108,32,116,111,32,116,104, - 101,10,32,32,32,32,105,109,112,111,114,116,32,115,121,115, - 116,101,109,46,10,10,32,32,32,32,84,104,101,32,108,111, - 97,100,101,114,32,109,117,115,116,32,116,97,107,101,32,97, - 32,115,112,101,99,32,97,115,32,105,116,115,32,111,110,108, - 121,32,95,95,105,110,105,116,95,95,40,41,32,97,114,103, - 46,10,10,32,32,32,32,78,122,9,60,117,110,107,110,111, - 119,110,62,218,12,103,101,116,95,102,105,108,101,110,97,109, - 101,169,1,218,6,111,114,105,103,105,110,84,218,10,105,115, - 95,112,97,99,107,97,103,101,114,0,0,0,0,41,21,114, - 153,0,0,0,114,203,0,0,0,114,142,0,0,0,114,18, - 0,0,0,114,103,0,0,0,114,86,0,0,0,114,67,0, - 0,0,114,82,0,0,0,114,76,0,0,0,114,159,0,0, - 0,218,10,77,111,100,117,108,101,83,112,101,99,90,13,95, - 115,101,116,95,102,105,108,101,97,116,116,114,218,27,95,103, - 101,116,95,115,117,112,112,111,114,116,101,100,95,102,105,108, - 101,95,108,111,97,100,101,114,115,114,58,0,0,0,114,136, - 0,0,0,114,164,0,0,0,218,9,95,80,79,80,85,76, - 65,84,69,114,206,0,0,0,114,202,0,0,0,114,74,0, - 0,0,114,61,0,0,0,41,9,114,141,0,0,0,90,8, - 108,111,99,97,116,105,111,110,114,164,0,0,0,114,202,0, - 0,0,218,4,115,112,101,99,218,12,108,111,97,100,101,114, - 95,99,108,97,115,115,218,8,115,117,102,102,105,120,101,115, - 114,206,0,0,0,90,7,100,105,114,110,97,109,101,114,7, - 0,0,0,114,7,0,0,0,114,8,0,0,0,218,23,115, - 112,101,99,95,102,114,111,109,95,102,105,108,101,95,108,111, - 99,97,116,105,111,110,209,2,0,0,115,84,0,0,0,8, - 12,4,4,10,1,2,2,14,1,12,1,4,1,2,255,2, - 252,10,7,8,1,2,1,18,1,12,1,4,1,2,255,16, - 9,6,1,8,3,14,1,14,1,10,1,6,1,4,1,2, - 253,4,5,8,3,10,2,2,1,14,1,12,1,4,1,2, - 255,4,3,6,1,2,128,6,2,10,1,4,1,12,1,12, - 1,4,2,114,213,0,0,0,99,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,4,0,0,0,64,0,0, - 0,115,88,0,0,0,101,0,90,1,100,0,90,2,100,1, - 90,3,100,2,90,4,100,3,90,5,101,6,111,15,100,4, - 101,7,118,0,90,8,101,9,100,5,100,6,132,0,131,1, - 90,10,101,11,100,7,100,8,132,0,131,1,90,12,101,11, - 100,14,100,10,100,11,132,1,131,1,90,13,101,11,100,15, - 100,12,100,13,132,1,131,1,90,14,100,9,83,0,41,16, - 218,21,87,105,110,100,111,119,115,82,101,103,105,115,116,114, - 121,70,105,110,100,101,114,122,62,77,101,116,97,32,112,97, - 116,104,32,102,105,110,100,101,114,32,102,111,114,32,109,111, - 100,117,108,101,115,32,100,101,99,108,97,114,101,100,32,105, - 110,32,116,104,101,32,87,105,110,100,111,119,115,32,114,101, - 103,105,115,116,114,121,46,122,59,83,111,102,116,119,97,114, - 101,92,80,121,116,104,111,110,92,80,121,116,104,111,110,67, - 111,114,101,92,123,115,121,115,95,118,101,114,115,105,111,110, - 125,92,77,111,100,117,108,101,115,92,123,102,117,108,108,110, - 97,109,101,125,122,65,83,111,102,116,119,97,114,101,92,80, - 121,116,104,111,110,92,80,121,116,104,111,110,67,111,114,101, - 92,123,115,121,115,95,118,101,114,115,105,111,110,125,92,77, - 111,100,117,108,101,115,92,123,102,117,108,108,110,97,109,101, - 125,92,68,101,98,117,103,122,6,95,100,46,112,121,100,99, - 1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0, - 8,0,0,0,67,0,0,0,115,50,0,0,0,122,8,116, - 0,160,1,116,0,106,2,124,0,161,2,87,0,83,0,4, - 0,116,3,121,24,1,0,1,0,1,0,116,0,160,1,116, - 0,106,4,124,0,161,2,6,0,89,0,83,0,119,0,114, - 69,0,0,0,41,5,218,6,119,105,110,114,101,103,90,7, - 79,112,101,110,75,101,121,90,17,72,75,69,89,95,67,85, - 82,82,69,78,84,95,85,83,69,82,114,76,0,0,0,90, - 18,72,75,69,89,95,76,79,67,65,76,95,77,65,67,72, - 73,78,69,114,19,0,0,0,114,7,0,0,0,114,7,0, - 0,0,114,8,0,0,0,218,14,95,111,112,101,110,95,114, - 101,103,105,115,116,114,121,38,3,0,0,115,10,0,0,0, - 2,2,16,1,12,1,18,1,2,255,122,36,87,105,110,100, - 111,119,115,82,101,103,105,115,116,114,121,70,105,110,100,101, - 114,46,95,111,112,101,110,95,114,101,103,105,115,116,114,121, - 99,2,0,0,0,0,0,0,0,0,0,0,0,6,0,0, - 0,8,0,0,0,67,0,0,0,115,134,0,0,0,124,0, - 106,0,114,7,124,0,106,1,125,2,110,3,124,0,106,2, - 125,2,124,2,106,3,124,1,100,1,116,4,106,5,100,0, - 100,2,133,2,25,0,22,0,100,3,141,2,125,3,122,32, - 124,0,160,6,124,3,161,1,143,16,125,4,116,7,160,8, - 124,4,100,4,161,2,125,5,87,0,100,0,4,0,4,0, - 131,3,1,0,87,0,124,5,83,0,49,0,115,49,119,1, - 1,0,1,0,1,0,89,0,1,0,87,0,124,5,83,0, - 4,0,116,9,121,66,1,0,1,0,1,0,89,0,100,0, - 83,0,119,0,41,5,78,122,5,37,100,46,37,100,114,44, - 0,0,0,41,2,114,163,0,0,0,90,11,115,121,115,95, - 118,101,114,115,105,111,110,114,10,0,0,0,41,10,218,11, - 68,69,66,85,71,95,66,85,73,76,68,218,18,82,69,71, - 73,83,84,82,89,95,75,69,89,95,68,69,66,85,71,218, - 12,82,69,71,73,83,84,82,89,95,75,69,89,114,89,0, - 0,0,114,15,0,0,0,218,12,118,101,114,115,105,111,110, - 95,105,110,102,111,114,216,0,0,0,114,215,0,0,0,90, - 10,81,117,101,114,121,86,97,108,117,101,114,76,0,0,0, - 41,6,218,3,99,108,115,114,163,0,0,0,90,12,114,101, - 103,105,115,116,114,121,95,107,101,121,114,20,0,0,0,90, - 4,104,107,101,121,218,8,102,105,108,101,112,97,116,104,114, - 7,0,0,0,114,7,0,0,0,114,8,0,0,0,218,16, - 95,115,101,97,114,99,104,95,114,101,103,105,115,116,114,121, - 45,3,0,0,115,32,0,0,0,6,2,8,1,6,2,6, - 1,16,1,6,255,2,2,12,1,14,1,12,255,4,4,18, - 252,4,4,12,254,6,1,2,255,122,38,87,105,110,100,111, - 119,115,82,101,103,105,115,116,114,121,70,105,110,100,101,114, - 46,95,115,101,97,114,99,104,95,114,101,103,105,115,116,114, - 121,78,99,4,0,0,0,0,0,0,0,0,0,0,0,8, - 0,0,0,8,0,0,0,67,0,0,0,115,120,0,0,0, - 124,0,160,0,124,1,161,1,125,4,124,4,100,0,117,0, - 114,11,100,0,83,0,122,6,116,1,124,4,131,1,1,0, - 87,0,110,10,4,0,116,2,121,27,1,0,1,0,1,0, - 89,0,100,0,83,0,119,0,116,3,131,0,68,0,93,26, - 92,2,125,5,125,6,124,4,160,4,116,5,124,6,131,1, - 161,1,114,57,116,6,106,7,124,1,124,5,124,1,124,4, - 131,2,124,4,100,1,141,3,125,7,124,7,2,0,1,0, - 83,0,113,31,100,0,83,0,41,2,78,114,204,0,0,0, - 41,8,114,223,0,0,0,114,75,0,0,0,114,76,0,0, - 0,114,208,0,0,0,114,58,0,0,0,114,136,0,0,0, - 114,159,0,0,0,218,16,115,112,101,99,95,102,114,111,109, - 95,108,111,97,100,101,114,41,8,114,221,0,0,0,114,163, - 0,0,0,114,65,0,0,0,218,6,116,97,114,103,101,116, - 114,222,0,0,0,114,164,0,0,0,114,212,0,0,0,114, - 210,0,0,0,114,7,0,0,0,114,7,0,0,0,114,8, - 0,0,0,218,9,102,105,110,100,95,115,112,101,99,60,3, - 0,0,115,34,0,0,0,10,2,8,1,4,1,2,1,12, - 1,12,1,6,1,2,255,14,2,14,1,6,1,8,1,2, - 1,6,254,8,3,2,252,4,255,122,31,87,105,110,100,111, - 119,115,82,101,103,105,115,116,114,121,70,105,110,100,101,114, - 46,102,105,110,100,95,115,112,101,99,99,3,0,0,0,0, - 0,0,0,0,0,0,0,4,0,0,0,4,0,0,0,67, - 0,0,0,115,42,0,0,0,116,0,160,1,100,1,116,2, - 161,2,1,0,124,0,160,3,124,1,124,2,161,2,125,3, - 124,3,100,2,117,1,114,19,124,3,106,4,83,0,100,2, - 83,0,41,3,122,106,70,105,110,100,32,109,111,100,117,108, - 101,32,110,97,109,101,100,32,105,110,32,116,104,101,32,114, - 101,103,105,115,116,114,121,46,10,10,32,32,32,32,32,32, - 32,32,84,104,105,115,32,109,101,116,104,111,100,32,105,115, - 32,100,101,112,114,101,99,97,116,101,100,46,32,32,85,115, - 101,32,102,105,110,100,95,115,112,101,99,40,41,32,105,110, - 115,116,101,97,100,46,10,10,32,32,32,32,32,32,32,32, - 122,112,87,105,110,100,111,119,115,82,101,103,105,115,116,114, - 121,70,105,110,100,101,114,46,102,105,110,100,95,109,111,100, - 117,108,101,40,41,32,105,115,32,100,101,112,114,101,99,97, - 116,101,100,32,97,110,100,32,115,108,97,116,101,100,32,102, - 111,114,32,114,101,109,111,118,97,108,32,105,110,32,80,121, - 116,104,111,110,32,51,46,49,50,59,32,117,115,101,32,102, - 105,110,100,95,115,112,101,99,40,41,32,105,110,115,116,101, - 97,100,78,169,5,114,99,0,0,0,114,100,0,0,0,114, - 101,0,0,0,114,226,0,0,0,114,164,0,0,0,169,4, - 114,221,0,0,0,114,163,0,0,0,114,65,0,0,0,114, - 210,0,0,0,114,7,0,0,0,114,7,0,0,0,114,8, - 0,0,0,218,11,102,105,110,100,95,109,111,100,117,108,101, - 76,3,0,0,115,14,0,0,0,6,7,2,2,4,254,12, - 3,8,1,6,1,4,2,122,33,87,105,110,100,111,119,115, - 82,101,103,105,115,116,114,121,70,105,110,100,101,114,46,102, - 105,110,100,95,109,111,100,117,108,101,169,2,78,78,114,69, - 0,0,0,41,15,114,150,0,0,0,114,149,0,0,0,114, - 151,0,0,0,114,152,0,0,0,114,219,0,0,0,114,218, - 0,0,0,218,11,95,77,83,95,87,73,78,68,79,87,83, - 218,18,69,88,84,69,78,83,73,79,78,95,83,85,70,70, - 73,88,69,83,114,217,0,0,0,218,12,115,116,97,116,105, - 99,109,101,116,104,111,100,114,216,0,0,0,218,11,99,108, - 97,115,115,109,101,116,104,111,100,114,223,0,0,0,114,226, - 0,0,0,114,229,0,0,0,114,7,0,0,0,114,7,0, - 0,0,114,7,0,0,0,114,8,0,0,0,114,214,0,0, - 0,26,3,0,0,115,30,0,0,0,8,0,4,2,2,3, - 2,255,2,4,2,255,12,3,2,2,10,1,2,6,10,1, - 2,14,12,1,2,15,16,1,114,214,0,0,0,99,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0, - 0,0,64,0,0,0,115,48,0,0,0,101,0,90,1,100, - 0,90,2,100,1,90,3,100,2,100,3,132,0,90,4,100, - 4,100,5,132,0,90,5,100,6,100,7,132,0,90,6,100, - 8,100,9,132,0,90,7,100,10,83,0,41,11,218,13,95, - 76,111,97,100,101,114,66,97,115,105,99,115,122,83,66,97, - 115,101,32,99,108,97,115,115,32,111,102,32,99,111,109,109, - 111,110,32,99,111,100,101,32,110,101,101,100,101,100,32,98, - 121,32,98,111,116,104,32,83,111,117,114,99,101,76,111,97, - 100,101,114,32,97,110,100,10,32,32,32,32,83,111,117,114, - 99,101,108,101,115,115,70,105,108,101,76,111,97,100,101,114, - 46,99,2,0,0,0,0,0,0,0,0,0,0,0,5,0, - 0,0,4,0,0,0,67,0,0,0,115,64,0,0,0,116, - 0,124,0,160,1,124,1,161,1,131,1,100,1,25,0,125, - 2,124,2,160,2,100,2,100,1,161,2,100,3,25,0,125, - 3,124,1,160,3,100,2,161,1,100,4,25,0,125,4,124, - 3,100,5,107,2,111,31,124,4,100,5,107,3,83,0,41, - 6,122,141,67,111,110,99,114,101,116,101,32,105,109,112,108, - 101,109,101,110,116,97,116,105,111,110,32,111,102,32,73,110, - 115,112,101,99,116,76,111,97,100,101,114,46,105,115,95,112, - 97,99,107,97,103,101,32,98,121,32,99,104,101,99,107,105, - 110,103,32,105,102,10,32,32,32,32,32,32,32,32,116,104, - 101,32,112,97,116,104,32,114,101,116,117,114,110,101,100,32, - 98,121,32,103,101,116,95,102,105,108,101,110,97,109,101,32, - 104,97,115,32,97,32,102,105,108,101,110,97,109,101,32,111, - 102,32,39,95,95,105,110,105,116,95,95,46,112,121,39,46, - 114,3,0,0,0,114,97,0,0,0,114,0,0,0,0,114, - 44,0,0,0,218,8,95,95,105,110,105,116,95,95,41,4, - 114,74,0,0,0,114,203,0,0,0,114,125,0,0,0,114, - 104,0,0,0,41,5,114,143,0,0,0,114,163,0,0,0, - 114,120,0,0,0,90,13,102,105,108,101,110,97,109,101,95, - 98,97,115,101,90,9,116,97,105,108,95,110,97,109,101,114, - 7,0,0,0,114,7,0,0,0,114,8,0,0,0,114,206, - 0,0,0,98,3,0,0,115,8,0,0,0,18,3,16,1, - 14,1,16,1,122,24,95,76,111,97,100,101,114,66,97,115, - 105,99,115,46,105,115,95,112,97,99,107,97,103,101,99,2, - 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,1, - 0,0,0,67,0,0,0,114,23,0,0,0,169,2,122,42, - 85,115,101,32,100,101,102,97,117,108,116,32,115,101,109,97, - 110,116,105,99,115,32,102,111,114,32,109,111,100,117,108,101, - 32,99,114,101,97,116,105,111,110,46,78,114,7,0,0,0, - 169,2,114,143,0,0,0,114,210,0,0,0,114,7,0,0, - 0,114,7,0,0,0,114,8,0,0,0,218,13,99,114,101, - 97,116,101,95,109,111,100,117,108,101,106,3,0,0,243,2, - 0,0,0,4,0,122,27,95,76,111,97,100,101,114,66,97, - 115,105,99,115,46,99,114,101,97,116,101,95,109,111,100,117, - 108,101,99,2,0,0,0,0,0,0,0,0,0,0,0,3, - 0,0,0,5,0,0,0,67,0,0,0,115,56,0,0,0, - 124,0,160,0,124,1,106,1,161,1,125,2,124,2,100,1, - 117,0,114,18,116,2,100,2,160,3,124,1,106,1,161,1, - 131,1,130,1,116,4,160,5,116,6,124,2,124,1,106,7, - 161,3,1,0,100,1,83,0,41,3,122,19,69,120,101,99, - 117,116,101,32,116,104,101,32,109,111,100,117,108,101,46,78, - 122,52,99,97,110,110,111,116,32,108,111,97,100,32,109,111, - 100,117,108,101,32,123,33,114,125,32,119,104,101,110,32,103, - 101,116,95,99,111,100,101,40,41,32,114,101,116,117,114,110, - 115,32,78,111,110,101,41,8,218,8,103,101,116,95,99,111, - 100,101,114,150,0,0,0,114,142,0,0,0,114,89,0,0, - 0,114,159,0,0,0,218,25,95,99,97,108,108,95,119,105, - 116,104,95,102,114,97,109,101,115,95,114,101,109,111,118,101, - 100,218,4,101,120,101,99,114,156,0,0,0,41,3,114,143, - 0,0,0,218,6,109,111,100,117,108,101,114,188,0,0,0, - 114,7,0,0,0,114,7,0,0,0,114,8,0,0,0,218, - 11,101,120,101,99,95,109,111,100,117,108,101,109,3,0,0, - 115,12,0,0,0,12,2,8,1,4,1,8,1,4,255,20, - 2,122,25,95,76,111,97,100,101,114,66,97,115,105,99,115, - 46,101,120,101,99,95,109,111,100,117,108,101,99,2,0,0, - 0,0,0,0,0,0,0,0,0,2,0,0,0,4,0,0, - 0,67,0,0,0,115,12,0,0,0,116,0,160,1,124,0, - 124,1,161,2,83,0,41,1,122,26,84,104,105,115,32,109, - 101,116,104,111,100,32,105,115,32,100,101,112,114,101,99,97, - 116,101,100,46,41,2,114,159,0,0,0,218,17,95,108,111, - 97,100,95,109,111,100,117,108,101,95,115,104,105,109,169,2, - 114,143,0,0,0,114,163,0,0,0,114,7,0,0,0,114, - 7,0,0,0,114,8,0,0,0,218,11,108,111,97,100,95, - 109,111,100,117,108,101,117,3,0,0,115,2,0,0,0,12, - 3,122,25,95,76,111,97,100,101,114,66,97,115,105,99,115, - 46,108,111,97,100,95,109,111,100,117,108,101,78,41,8,114, - 150,0,0,0,114,149,0,0,0,114,151,0,0,0,114,152, - 0,0,0,114,206,0,0,0,114,239,0,0,0,114,245,0, - 0,0,114,248,0,0,0,114,7,0,0,0,114,7,0,0, - 0,114,7,0,0,0,114,8,0,0,0,114,235,0,0,0, - 93,3,0,0,115,12,0,0,0,8,0,4,2,8,3,8, - 8,8,3,12,8,114,235,0,0,0,99,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,64, - 0,0,0,115,74,0,0,0,101,0,90,1,100,0,90,2, - 100,1,100,2,132,0,90,3,100,3,100,4,132,0,90,4, - 100,5,100,6,132,0,90,5,100,7,100,8,132,0,90,6, - 100,9,100,10,132,0,90,7,100,11,100,12,156,1,100,13, - 100,14,132,2,90,8,100,15,100,16,132,0,90,9,100,17, - 83,0,41,18,218,12,83,111,117,114,99,101,76,111,97,100, - 101,114,99,2,0,0,0,0,0,0,0,0,0,0,0,2, - 0,0,0,1,0,0,0,67,0,0,0,115,4,0,0,0, - 116,0,130,1,41,1,122,165,79,112,116,105,111,110,97,108, - 32,109,101,116,104,111,100,32,116,104,97,116,32,114,101,116, - 117,114,110,115,32,116,104,101,32,109,111,100,105,102,105,99, - 97,116,105,111,110,32,116,105,109,101,32,40,97,110,32,105, - 110,116,41,32,102,111,114,32,116,104,101,10,32,32,32,32, - 32,32,32,32,115,112,101,99,105,102,105,101,100,32,112,97, - 116,104,32,40,97,32,115,116,114,41,46,10,10,32,32,32, - 32,32,32,32,32,82,97,105,115,101,115,32,79,83,69,114, - 114,111,114,32,119,104,101,110,32,116,104,101,32,112,97,116, - 104,32,99,97,110,110,111,116,32,98,101,32,104,97,110,100, - 108,101,100,46,10,32,32,32,32,32,32,32,32,41,1,114, - 76,0,0,0,169,2,114,143,0,0,0,114,65,0,0,0, - 114,7,0,0,0,114,7,0,0,0,114,8,0,0,0,218, - 10,112,97,116,104,95,109,116,105,109,101,125,3,0,0,115, - 2,0,0,0,4,6,122,23,83,111,117,114,99,101,76,111, - 97,100,101,114,46,112,97,116,104,95,109,116,105,109,101,99, - 2,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0, - 4,0,0,0,67,0,0,0,115,14,0,0,0,100,1,124, - 0,160,0,124,1,161,1,105,1,83,0,41,2,97,158,1, - 0,0,79,112,116,105,111,110,97,108,32,109,101,116,104,111, - 100,32,114,101,116,117,114,110,105,110,103,32,97,32,109,101, - 116,97,100,97,116,97,32,100,105,99,116,32,102,111,114,32, - 116,104,101,32,115,112,101,99,105,102,105,101,100,10,32,32, - 32,32,32,32,32,32,112,97,116,104,32,40,97,32,115,116, - 114,41,46,10,10,32,32,32,32,32,32,32,32,80,111,115, - 115,105,98,108,101,32,107,101,121,115,58,10,32,32,32,32, - 32,32,32,32,45,32,39,109,116,105,109,101,39,32,40,109, - 97,110,100,97,116,111,114,121,41,32,105,115,32,116,104,101, - 32,110,117,109,101,114,105,99,32,116,105,109,101,115,116,97, - 109,112,32,111,102,32,108,97,115,116,32,115,111,117,114,99, - 101,10,32,32,32,32,32,32,32,32,32,32,99,111,100,101, - 32,109,111,100,105,102,105,99,97,116,105,111,110,59,10,32, - 32,32,32,32,32,32,32,45,32,39,115,105,122,101,39,32, - 40,111,112,116,105,111,110,97,108,41,32,105,115,32,116,104, - 101,32,115,105,122,101,32,105,110,32,98,121,116,101,115,32, - 111,102,32,116,104,101,32,115,111,117,114,99,101,32,99,111, - 100,101,46,10,10,32,32,32,32,32,32,32,32,73,109,112, - 108,101,109,101,110,116,105,110,103,32,116,104,105,115,32,109, - 101,116,104,111,100,32,97,108,108,111,119,115,32,116,104,101, - 32,108,111,97,100,101,114,32,116,111,32,114,101,97,100,32, - 98,121,116,101,99,111,100,101,32,102,105,108,101,115,46,10, - 32,32,32,32,32,32,32,32,82,97,105,115,101,115,32,79, - 83,69,114,114,111,114,32,119,104,101,110,32,116,104,101,32, - 112,97,116,104,32,99,97,110,110,111,116,32,98,101,32,104, - 97,110,100,108,101,100,46,10,32,32,32,32,32,32,32,32, - 114,193,0,0,0,41,1,114,251,0,0,0,114,250,0,0, - 0,114,7,0,0,0,114,7,0,0,0,114,8,0,0,0, - 218,10,112,97,116,104,95,115,116,97,116,115,133,3,0,0, - 115,2,0,0,0,14,12,122,23,83,111,117,114,99,101,76, - 111,97,100,101,114,46,112,97,116,104,95,115,116,97,116,115, - 99,4,0,0,0,0,0,0,0,0,0,0,0,4,0,0, - 0,4,0,0,0,67,0,0,0,115,12,0,0,0,124,0, - 160,0,124,2,124,3,161,2,83,0,41,1,122,228,79,112, - 116,105,111,110,97,108,32,109,101,116,104,111,100,32,119,104, - 105,99,104,32,119,114,105,116,101,115,32,100,97,116,97,32, - 40,98,121,116,101,115,41,32,116,111,32,97,32,102,105,108, - 101,32,112,97,116,104,32,40,97,32,115,116,114,41,46,10, - 10,32,32,32,32,32,32,32,32,73,109,112,108,101,109,101, - 110,116,105,110,103,32,116,104,105,115,32,109,101,116,104,111, - 100,32,97,108,108,111,119,115,32,102,111,114,32,116,104,101, - 32,119,114,105,116,105,110,103,32,111,102,32,98,121,116,101, - 99,111,100,101,32,102,105,108,101,115,46,10,10,32,32,32, - 32,32,32,32,32,84,104,101,32,115,111,117,114,99,101,32, - 112,97,116,104,32,105,115,32,110,101,101,100,101,100,32,105, - 110,32,111,114,100,101,114,32,116,111,32,99,111,114,114,101, - 99,116,108,121,32,116,114,97,110,115,102,101,114,32,112,101, - 114,109,105,115,115,105,111,110,115,10,32,32,32,32,32,32, - 32,32,41,1,218,8,115,101,116,95,100,97,116,97,41,4, - 114,143,0,0,0,114,134,0,0,0,90,10,99,97,99,104, - 101,95,112,97,116,104,114,41,0,0,0,114,7,0,0,0, - 114,7,0,0,0,114,8,0,0,0,218,15,95,99,97,99, - 104,101,95,98,121,116,101,99,111,100,101,147,3,0,0,115, - 2,0,0,0,12,8,122,28,83,111,117,114,99,101,76,111, - 97,100,101,114,46,95,99,97,99,104,101,95,98,121,116,101, - 99,111,100,101,99,3,0,0,0,0,0,0,0,0,0,0, - 0,3,0,0,0,1,0,0,0,67,0,0,0,114,23,0, - 0,0,41,2,122,150,79,112,116,105,111,110,97,108,32,109, - 101,116,104,111,100,32,119,104,105,99,104,32,119,114,105,116, - 101,115,32,100,97,116,97,32,40,98,121,116,101,115,41,32, - 116,111,32,97,32,102,105,108,101,32,112,97,116,104,32,40, - 97,32,115,116,114,41,46,10,10,32,32,32,32,32,32,32, - 32,73,109,112,108,101,109,101,110,116,105,110,103,32,116,104, - 105,115,32,109,101,116,104,111,100,32,97,108,108,111,119,115, - 32,102,111,114,32,116,104,101,32,119,114,105,116,105,110,103, - 32,111,102,32,98,121,116,101,99,111,100,101,32,102,105,108, - 101,115,46,10,32,32,32,32,32,32,32,32,78,114,7,0, - 0,0,41,3,114,143,0,0,0,114,65,0,0,0,114,41, - 0,0,0,114,7,0,0,0,114,7,0,0,0,114,8,0, - 0,0,114,253,0,0,0,157,3,0,0,114,240,0,0,0, - 122,21,83,111,117,114,99,101,76,111,97,100,101,114,46,115, - 101,116,95,100,97,116,97,99,2,0,0,0,0,0,0,0, - 0,0,0,0,5,0,0,0,10,0,0,0,67,0,0,0, - 115,70,0,0,0,124,0,160,0,124,1,161,1,125,2,122, - 10,124,0,160,1,124,2,161,1,125,3,87,0,116,4,124, - 3,131,1,83,0,4,0,116,2,121,34,1,0,125,4,1, - 0,122,7,116,3,100,1,124,1,100,2,141,2,124,4,130, - 2,100,3,125,4,126,4,119,1,119,0,41,4,122,52,67, - 111,110,99,114,101,116,101,32,105,109,112,108,101,109,101,110, - 116,97,116,105,111,110,32,111,102,32,73,110,115,112,101,99, - 116,76,111,97,100,101,114,46,103,101,116,95,115,111,117,114, - 99,101,46,122,39,115,111,117,114,99,101,32,110,111,116,32, - 97,118,97,105,108,97,98,108,101,32,116,104,114,111,117,103, - 104,32,103,101,116,95,100,97,116,97,40,41,114,140,0,0, - 0,78,41,5,114,203,0,0,0,218,8,103,101,116,95,100, - 97,116,97,114,76,0,0,0,114,142,0,0,0,114,200,0, - 0,0,41,5,114,143,0,0,0,114,163,0,0,0,114,65, - 0,0,0,114,198,0,0,0,218,3,101,120,99,114,7,0, - 0,0,114,7,0,0,0,114,8,0,0,0,218,10,103,101, - 116,95,115,111,117,114,99,101,164,3,0,0,115,24,0,0, - 0,10,2,2,1,12,1,8,4,14,253,4,1,2,1,4, - 255,2,1,2,255,8,128,2,255,122,23,83,111,117,114,99, - 101,76,111,97,100,101,114,46,103,101,116,95,115,111,117,114, - 99,101,114,130,0,0,0,41,1,218,9,95,111,112,116,105, - 109,105,122,101,99,3,0,0,0,0,0,0,0,1,0,0, - 0,4,0,0,0,8,0,0,0,67,0,0,0,115,22,0, - 0,0,116,0,106,1,116,2,124,1,124,2,100,1,100,2, - 124,3,100,3,141,6,83,0,41,4,122,130,82,101,116,117, - 114,110,32,116,104,101,32,99,111,100,101,32,111,98,106,101, - 99,116,32,99,111,109,112,105,108,101,100,32,102,114,111,109, - 32,115,111,117,114,99,101,46,10,10,32,32,32,32,32,32, - 32,32,84,104,101,32,39,100,97,116,97,39,32,97,114,103, - 117,109,101,110,116,32,99,97,110,32,98,101,32,97,110,121, - 32,111,98,106,101,99,116,32,116,121,112,101,32,116,104,97, - 116,32,99,111,109,112,105,108,101,40,41,32,115,117,112,112, - 111,114,116,115,46,10,32,32,32,32,32,32,32,32,114,243, - 0,0,0,84,41,2,218,12,100,111,110,116,95,105,110,104, - 101,114,105,116,114,108,0,0,0,41,3,114,159,0,0,0, - 114,242,0,0,0,218,7,99,111,109,112,105,108,101,41,4, - 114,143,0,0,0,114,41,0,0,0,114,65,0,0,0,114, - 2,1,0,0,114,7,0,0,0,114,7,0,0,0,114,8, - 0,0,0,218,14,115,111,117,114,99,101,95,116,111,95,99, - 111,100,101,174,3,0,0,115,6,0,0,0,12,5,4,1, - 6,255,122,27,83,111,117,114,99,101,76,111,97,100,101,114, - 46,115,111,117,114,99,101,95,116,111,95,99,111,100,101,99, - 2,0,0,0,0,0,0,0,0,0,0,0,15,0,0,0, - 9,0,0,0,67,0,0,0,115,2,2,0,0,124,0,160, - 0,124,1,161,1,125,2,100,1,125,3,100,1,125,4,100, - 1,125,5,100,2,125,6,100,3,125,7,122,6,116,1,124, - 2,131,1,125,8,87,0,110,11,4,0,116,2,121,32,1, - 0,1,0,1,0,100,1,125,8,89,0,110,144,119,0,122, - 7,124,0,160,3,124,2,161,1,125,9,87,0,110,9,4, - 0,116,4,121,49,1,0,1,0,1,0,89,0,110,127,119, - 0,116,5,124,9,100,4,25,0,131,1,125,3,122,7,124, - 0,160,6,124,8,161,1,125,10,87,0,110,9,4,0,116, - 4,121,72,1,0,1,0,1,0,89,0,110,104,119,0,124, - 1,124,8,100,5,156,2,125,11,122,71,116,7,124,10,124, - 1,124,11,131,3,125,12,116,8,124,10,131,1,100,6,100, - 1,133,2,25,0,125,13,124,12,100,7,64,0,100,8,107, - 3,125,6,124,6,114,138,124,12,100,9,64,0,100,8,107, - 3,125,7,116,9,106,10,100,10,107,3,114,137,124,7,115, - 119,116,9,106,10,100,11,107,2,114,137,124,0,160,6,124, - 2,161,1,125,4,116,9,160,11,116,12,124,4,161,2,125, - 5,116,13,124,10,124,5,124,1,124,11,131,4,1,0,110, - 10,116,14,124,10,124,3,124,9,100,12,25,0,124,1,124, - 11,131,5,1,0,87,0,110,11,4,0,116,15,116,16,102, - 2,121,160,1,0,1,0,1,0,89,0,110,16,119,0,116, - 17,160,18,100,13,124,8,124,2,161,3,1,0,116,19,124, - 13,124,1,124,8,124,2,100,14,141,4,83,0,124,4,100, - 1,117,0,114,185,124,0,160,6,124,2,161,1,125,4,124, - 0,160,20,124,4,124,2,161,2,125,14,116,17,160,18,100, - 15,124,2,161,2,1,0,116,21,106,22,115,255,124,8,100, - 1,117,1,114,255,124,3,100,1,117,1,114,255,124,6,114, - 226,124,5,100,1,117,0,114,219,116,9,160,11,124,4,161, - 1,125,5,116,23,124,14,124,5,124,7,131,3,125,10,110, - 8,116,24,124,14,124,3,116,25,124,4,131,1,131,3,125, - 10,122,10,124,0,160,26,124,2,124,8,124,10,161,3,1, - 0,87,0,124,14,83,0,4,0,116,2,121,254,1,0,1, - 0,1,0,89,0,124,14,83,0,119,0,124,14,83,0,41, - 16,122,190,67,111,110,99,114,101,116,101,32,105,109,112,108, - 101,109,101,110,116,97,116,105,111,110,32,111,102,32,73,110, - 115,112,101,99,116,76,111,97,100,101,114,46,103,101,116,95, - 99,111,100,101,46,10,10,32,32,32,32,32,32,32,32,82, - 101,97,100,105,110,103,32,111,102,32,98,121,116,101,99,111, - 100,101,32,114,101,113,117,105,114,101,115,32,112,97,116,104, - 95,115,116,97,116,115,32,116,111,32,98,101,32,105,109,112, - 108,101,109,101,110,116,101,100,46,32,84,111,32,119,114,105, - 116,101,10,32,32,32,32,32,32,32,32,98,121,116,101,99, - 111,100,101,44,32,115,101,116,95,100,97,116,97,32,109,117, - 115,116,32,97,108,115,111,32,98,101,32,105,109,112,108,101, - 109,101,110,116,101,100,46,10,10,32,32,32,32,32,32,32, - 32,78,70,84,114,193,0,0,0,114,183,0,0,0,114,169, - 0,0,0,114,3,0,0,0,114,0,0,0,0,114,44,0, - 0,0,90,5,110,101,118,101,114,90,6,97,108,119,97,121, - 115,218,4,115,105,122,101,122,13,123,125,32,109,97,116,99, - 104,101,115,32,123,125,41,3,114,141,0,0,0,114,132,0, - 0,0,114,134,0,0,0,122,19,99,111,100,101,32,111,98, - 106,101,99,116,32,102,114,111,109,32,123,125,41,27,114,203, - 0,0,0,114,121,0,0,0,114,107,0,0,0,114,252,0, - 0,0,114,76,0,0,0,114,33,0,0,0,114,255,0,0, - 0,114,176,0,0,0,218,10,109,101,109,111,114,121,118,105, - 101,119,114,187,0,0,0,90,21,99,104,101,99,107,95,104, - 97,115,104,95,98,97,115,101,100,95,112,121,99,115,114,181, - 0,0,0,218,17,95,82,65,87,95,77,65,71,73,67,95, - 78,85,77,66,69,82,114,182,0,0,0,114,180,0,0,0, - 114,142,0,0,0,114,174,0,0,0,114,159,0,0,0,114, - 173,0,0,0,114,189,0,0,0,114,5,1,0,0,114,15, - 0,0,0,218,19,100,111,110,116,95,119,114,105,116,101,95, - 98,121,116,101,99,111,100,101,114,195,0,0,0,114,194,0, - 0,0,114,4,0,0,0,114,254,0,0,0,41,15,114,143, - 0,0,0,114,163,0,0,0,114,134,0,0,0,114,178,0, - 0,0,114,198,0,0,0,114,181,0,0,0,90,10,104,97, - 115,104,95,98,97,115,101,100,90,12,99,104,101,99,107,95, - 115,111,117,114,99,101,114,132,0,0,0,218,2,115,116,114, - 41,0,0,0,114,175,0,0,0,114,16,0,0,0,90,10, - 98,121,116,101,115,95,100,97,116,97,90,11,99,111,100,101, - 95,111,98,106,101,99,116,114,7,0,0,0,114,7,0,0, - 0,114,8,0,0,0,114,241,0,0,0,182,3,0,0,115, - 170,0,0,0,10,7,4,1,4,1,4,1,4,1,4,1, - 2,1,12,1,12,1,8,1,2,255,2,3,14,1,12,1, - 4,1,2,255,12,3,2,1,14,1,12,1,4,1,2,255, - 2,4,2,1,6,254,2,4,12,1,16,1,12,1,4,1, - 12,1,10,1,2,1,2,255,8,2,2,254,10,3,4,1, - 2,1,2,1,4,254,8,4,2,1,4,255,2,128,2,3, - 2,1,2,1,6,1,2,1,2,1,4,251,4,128,16,7, - 4,1,2,255,8,3,2,1,4,255,6,2,2,1,2,1, - 6,254,8,3,10,1,12,1,12,1,14,1,6,1,2,255, - 4,2,8,1,10,1,14,1,6,2,6,1,4,255,2,2, - 16,1,4,3,12,254,2,1,4,1,2,254,4,2,122,21, - 83,111,117,114,99,101,76,111,97,100,101,114,46,103,101,116, - 95,99,111,100,101,78,41,10,114,150,0,0,0,114,149,0, - 0,0,114,151,0,0,0,114,251,0,0,0,114,252,0,0, - 0,114,254,0,0,0,114,253,0,0,0,114,1,1,0,0, - 114,5,1,0,0,114,241,0,0,0,114,7,0,0,0,114, - 7,0,0,0,114,7,0,0,0,114,8,0,0,0,114,249, - 0,0,0,123,3,0,0,115,16,0,0,0,8,0,8,2, - 8,8,8,14,8,10,8,7,14,10,12,8,114,249,0,0, - 0,99,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,4,0,0,0,0,0,0,0,115,92,0,0,0,101, - 0,90,1,100,0,90,2,100,1,90,3,100,2,100,3,132, - 0,90,4,100,4,100,5,132,0,90,5,100,6,100,7,132, - 0,90,6,101,7,135,0,102,1,100,8,100,9,132,8,131, - 1,90,8,101,7,100,10,100,11,132,0,131,1,90,9,100, - 12,100,13,132,0,90,10,101,7,100,14,100,15,132,0,131, - 1,90,11,135,0,4,0,90,12,83,0,41,16,218,10,70, - 105,108,101,76,111,97,100,101,114,122,103,66,97,115,101,32, - 102,105,108,101,32,108,111,97,100,101,114,32,99,108,97,115, - 115,32,119,104,105,99,104,32,105,109,112,108,101,109,101,110, - 116,115,32,116,104,101,32,108,111,97,100,101,114,32,112,114, - 111,116,111,99,111,108,32,109,101,116,104,111,100,115,32,116, - 104,97,116,10,32,32,32,32,114,101,113,117,105,114,101,32, - 102,105,108,101,32,115,121,115,116,101,109,32,117,115,97,103, - 101,46,99,3,0,0,0,0,0,0,0,0,0,0,0,3, - 0,0,0,2,0,0,0,67,0,0,0,115,16,0,0,0, - 124,1,124,0,95,0,124,2,124,0,95,1,100,1,83,0, - 41,2,122,75,67,97,99,104,101,32,116,104,101,32,109,111, - 100,117,108,101,32,110,97,109,101,32,97,110,100,32,116,104, - 101,32,112,97,116,104,32,116,111,32,116,104,101,32,102,105, - 108,101,32,102,111,117,110,100,32,98,121,32,116,104,101,10, - 32,32,32,32,32,32,32,32,102,105,110,100,101,114,46,78, - 114,183,0,0,0,41,3,114,143,0,0,0,114,163,0,0, - 0,114,65,0,0,0,114,7,0,0,0,114,7,0,0,0, - 114,8,0,0,0,114,236,0,0,0,16,4,0,0,115,4, - 0,0,0,6,3,10,1,122,19,70,105,108,101,76,111,97, - 100,101,114,46,95,95,105,110,105,116,95,95,99,2,0,0, - 0,0,0,0,0,0,0,0,0,2,0,0,0,2,0,0, - 0,67,0,0,0,243,24,0,0,0,124,0,106,0,124,1, - 106,0,107,2,111,11,124,0,106,1,124,1,106,1,107,2, - 83,0,114,69,0,0,0,169,2,218,9,95,95,99,108,97, - 115,115,95,95,114,156,0,0,0,169,2,114,143,0,0,0, - 90,5,111,116,104,101,114,114,7,0,0,0,114,7,0,0, - 0,114,8,0,0,0,218,6,95,95,101,113,95,95,22,4, - 0,0,243,6,0,0,0,12,1,10,1,2,255,122,17,70, - 105,108,101,76,111,97,100,101,114,46,95,95,101,113,95,95, - 99,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0, - 0,3,0,0,0,67,0,0,0,243,20,0,0,0,116,0, - 124,0,106,1,131,1,116,0,124,0,106,2,131,1,65,0, - 83,0,114,69,0,0,0,169,3,218,4,104,97,115,104,114, - 141,0,0,0,114,65,0,0,0,169,1,114,143,0,0,0, - 114,7,0,0,0,114,7,0,0,0,114,8,0,0,0,218, - 8,95,95,104,97,115,104,95,95,26,4,0,0,243,2,0, - 0,0,20,1,122,19,70,105,108,101,76,111,97,100,101,114, - 46,95,95,104,97,115,104,95,95,99,2,0,0,0,0,0, - 0,0,0,0,0,0,2,0,0,0,3,0,0,0,3,0, - 0,0,115,16,0,0,0,116,0,116,1,124,0,131,2,160, - 2,124,1,161,1,83,0,41,1,122,100,76,111,97,100,32, - 97,32,109,111,100,117,108,101,32,102,114,111,109,32,97,32, - 102,105,108,101,46,10,10,32,32,32,32,32,32,32,32,84, - 104,105,115,32,109,101,116,104,111,100,32,105,115,32,100,101, - 112,114,101,99,97,116,101,100,46,32,32,85,115,101,32,101, - 120,101,99,95,109,111,100,117,108,101,40,41,32,105,110,115, - 116,101,97,100,46,10,10,32,32,32,32,32,32,32,32,41, - 3,218,5,115,117,112,101,114,114,11,1,0,0,114,248,0, - 0,0,114,247,0,0,0,169,1,114,14,1,0,0,114,7, - 0,0,0,114,8,0,0,0,114,248,0,0,0,29,4,0, - 0,115,2,0,0,0,16,10,122,22,70,105,108,101,76,111, - 97,100,101,114,46,108,111,97,100,95,109,111,100,117,108,101, - 99,2,0,0,0,0,0,0,0,0,0,0,0,2,0,0, - 0,1,0,0,0,67,0,0,0,243,6,0,0,0,124,0, - 106,0,83,0,169,1,122,58,82,101,116,117,114,110,32,116, - 104,101,32,112,97,116,104,32,116,111,32,116,104,101,32,115, - 111,117,114,99,101,32,102,105,108,101,32,97,115,32,102,111, - 117,110,100,32,98,121,32,116,104,101,32,102,105,110,100,101, - 114,46,114,71,0,0,0,114,247,0,0,0,114,7,0,0, - 0,114,7,0,0,0,114,8,0,0,0,114,203,0,0,0, - 41,4,0,0,243,2,0,0,0,6,3,122,23,70,105,108, - 101,76,111,97,100,101,114,46,103,101,116,95,102,105,108,101, - 110,97,109,101,99,2,0,0,0,0,0,0,0,0,0,0, - 0,3,0,0,0,8,0,0,0,67,0,0,0,115,128,0, - 0,0,116,0,124,0,116,1,116,2,102,2,131,2,114,36, - 116,3,160,4,116,5,124,1,131,1,161,1,143,12,125,2, - 124,2,160,6,161,0,87,0,2,0,100,1,4,0,4,0, - 131,3,1,0,83,0,49,0,115,29,119,1,1,0,1,0, - 1,0,89,0,1,0,100,1,83,0,116,3,160,7,124,1, - 100,2,161,2,143,12,125,2,124,2,160,6,161,0,87,0, - 2,0,100,1,4,0,4,0,131,3,1,0,83,0,49,0, - 115,57,119,1,1,0,1,0,1,0,89,0,1,0,100,1, - 83,0,41,3,122,39,82,101,116,117,114,110,32,116,104,101, - 32,100,97,116,97,32,102,114,111,109,32,112,97,116,104,32, - 97,115,32,114,97,119,32,98,121,116,101,115,46,78,218,1, - 114,41,8,114,185,0,0,0,114,249,0,0,0,218,19,69, - 120,116,101,110,115,105,111,110,70,105,108,101,76,111,97,100, - 101,114,114,91,0,0,0,90,9,111,112,101,110,95,99,111, - 100,101,114,109,0,0,0,90,4,114,101,97,100,114,92,0, - 0,0,41,3,114,143,0,0,0,114,65,0,0,0,114,94, - 0,0,0,114,7,0,0,0,114,7,0,0,0,114,8,0, - 0,0,114,255,0,0,0,46,4,0,0,115,14,0,0,0, - 14,2,16,1,6,1,36,255,14,3,6,1,36,255,122,19, - 70,105,108,101,76,111,97,100,101,114,46,103,101,116,95,100, - 97,116,97,99,2,0,0,0,0,0,0,0,0,0,0,0, - 3,0,0,0,2,0,0,0,67,0,0,0,115,20,0,0, - 0,100,1,100,2,108,0,109,1,125,2,1,0,124,2,124, - 0,131,1,83,0,41,3,78,114,0,0,0,0,41,1,218, - 10,70,105,108,101,82,101,97,100,101,114,41,2,218,17,105, - 109,112,111,114,116,108,105,98,46,114,101,97,100,101,114,115, - 114,31,1,0,0,41,3,114,143,0,0,0,114,244,0,0, - 0,114,31,1,0,0,114,7,0,0,0,114,7,0,0,0, - 114,8,0,0,0,218,19,103,101,116,95,114,101,115,111,117, - 114,99,101,95,114,101,97,100,101,114,55,4,0,0,115,4, - 0,0,0,12,2,8,1,122,30,70,105,108,101,76,111,97, - 100,101,114,46,103,101,116,95,114,101,115,111,117,114,99,101, - 95,114,101,97,100,101,114,41,13,114,150,0,0,0,114,149, - 0,0,0,114,151,0,0,0,114,152,0,0,0,114,236,0, - 0,0,114,16,1,0,0,114,22,1,0,0,114,160,0,0, - 0,114,248,0,0,0,114,203,0,0,0,114,255,0,0,0, - 114,33,1,0,0,90,13,95,95,99,108,97,115,115,99,101, - 108,108,95,95,114,7,0,0,0,114,7,0,0,0,114,25, - 1,0,0,114,8,0,0,0,114,11,1,0,0,11,4,0, - 0,115,24,0,0,0,8,0,4,2,8,3,8,6,8,4, - 2,3,14,1,2,11,10,1,8,4,2,9,18,1,114,11, - 1,0,0,99,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,3,0,0,0,64,0,0,0,115,46,0,0, - 0,101,0,90,1,100,0,90,2,100,1,90,3,100,2,100, - 3,132,0,90,4,100,4,100,5,132,0,90,5,100,6,100, - 7,156,1,100,8,100,9,132,2,90,6,100,10,83,0,41, - 11,218,16,83,111,117,114,99,101,70,105,108,101,76,111,97, - 100,101,114,122,62,67,111,110,99,114,101,116,101,32,105,109, - 112,108,101,109,101,110,116,97,116,105,111,110,32,111,102,32, - 83,111,117,114,99,101,76,111,97,100,101,114,32,117,115,105, - 110,103,32,116,104,101,32,102,105,108,101,32,115,121,115,116, - 101,109,46,99,2,0,0,0,0,0,0,0,0,0,0,0, - 3,0,0,0,3,0,0,0,67,0,0,0,115,22,0,0, - 0,116,0,124,1,131,1,125,2,124,2,106,1,124,2,106, - 2,100,1,156,2,83,0,41,2,122,33,82,101,116,117,114, - 110,32,116,104,101,32,109,101,116,97,100,97,116,97,32,102, - 111,114,32,116,104,101,32,112,97,116,104,46,41,2,114,193, - 0,0,0,114,6,1,0,0,41,3,114,75,0,0,0,218, - 8,115,116,95,109,116,105,109,101,90,7,115,116,95,115,105, - 122,101,41,3,114,143,0,0,0,114,65,0,0,0,114,10, - 1,0,0,114,7,0,0,0,114,7,0,0,0,114,8,0, - 0,0,114,252,0,0,0,65,4,0,0,115,4,0,0,0, - 8,2,14,1,122,27,83,111,117,114,99,101,70,105,108,101, - 76,111,97,100,101,114,46,112,97,116,104,95,115,116,97,116, - 115,99,4,0,0,0,0,0,0,0,0,0,0,0,5,0, - 0,0,5,0,0,0,67,0,0,0,115,24,0,0,0,116, - 0,124,1,131,1,125,4,124,0,106,1,124,2,124,3,124, - 4,100,1,141,3,83,0,41,2,78,169,1,218,5,95,109, - 111,100,101,41,2,114,139,0,0,0,114,253,0,0,0,41, - 5,114,143,0,0,0,114,134,0,0,0,114,132,0,0,0, - 114,41,0,0,0,114,78,0,0,0,114,7,0,0,0,114, - 7,0,0,0,114,8,0,0,0,114,254,0,0,0,70,4, - 0,0,115,4,0,0,0,8,2,16,1,122,32,83,111,117, - 114,99,101,70,105,108,101,76,111,97,100,101,114,46,95,99, - 97,99,104,101,95,98,121,116,101,99,111,100,101,114,87,0, - 0,0,114,36,1,0,0,99,3,0,0,0,0,0,0,0, - 1,0,0,0,9,0,0,0,11,0,0,0,67,0,0,0, - 115,254,0,0,0,116,0,124,1,131,1,92,2,125,4,125, - 5,103,0,125,6,124,4,114,31,116,1,124,4,131,1,115, - 31,116,0,124,4,131,1,92,2,125,4,125,7,124,6,160, - 2,124,7,161,1,1,0,124,4,114,31,116,1,124,4,131, - 1,114,14,116,3,124,6,131,1,68,0,93,49,125,7,116, - 4,124,4,124,7,131,2,125,4,122,7,116,5,160,6,124, - 4,161,1,1,0,87,0,113,35,4,0,116,7,121,58,1, - 0,1,0,1,0,89,0,113,35,4,0,116,8,121,84,1, - 0,125,8,1,0,122,15,116,9,160,10,100,1,124,4,124, - 8,161,3,1,0,87,0,89,0,100,2,125,8,126,8,1, - 0,100,2,83,0,100,2,125,8,126,8,119,1,119,0,122, - 15,116,11,124,1,124,2,124,3,131,3,1,0,116,9,160, - 10,100,3,124,1,161,2,1,0,87,0,100,2,83,0,4, - 0,116,8,121,126,1,0,125,8,1,0,122,14,116,9,160, - 10,100,1,124,1,124,8,161,3,1,0,87,0,89,0,100, - 2,125,8,126,8,100,2,83,0,100,2,125,8,126,8,119, - 1,119,0,41,4,122,27,87,114,105,116,101,32,98,121,116, - 101,115,32,100,97,116,97,32,116,111,32,97,32,102,105,108, - 101,46,122,27,99,111,117,108,100,32,110,111,116,32,99,114, - 101,97,116,101,32,123,33,114,125,58,32,123,33,114,125,78, - 122,12,99,114,101,97,116,101,100,32,123,33,114,125,41,12, - 114,74,0,0,0,114,83,0,0,0,114,61,0,0,0,218, - 8,114,101,118,101,114,115,101,100,114,67,0,0,0,114,18, - 0,0,0,90,5,109,107,100,105,114,218,15,70,105,108,101, - 69,120,105,115,116,115,69,114,114,111,114,114,76,0,0,0, - 114,159,0,0,0,114,173,0,0,0,114,95,0,0,0,41, - 9,114,143,0,0,0,114,65,0,0,0,114,41,0,0,0, - 114,37,1,0,0,218,6,112,97,114,101,110,116,114,120,0, - 0,0,114,63,0,0,0,114,68,0,0,0,114,0,1,0, - 0,114,7,0,0,0,114,7,0,0,0,114,8,0,0,0, - 114,253,0,0,0,75,4,0,0,115,56,0,0,0,12,2, - 4,1,12,2,12,1,10,1,12,254,12,4,10,1,2,1, - 14,1,12,1,4,2,14,1,6,3,4,1,4,255,16,2, - 8,128,2,251,2,6,12,1,18,1,14,1,8,2,2,1, - 18,255,8,128,2,254,122,25,83,111,117,114,99,101,70,105, - 108,101,76,111,97,100,101,114,46,115,101,116,95,100,97,116, - 97,78,41,7,114,150,0,0,0,114,149,0,0,0,114,151, - 0,0,0,114,152,0,0,0,114,252,0,0,0,114,254,0, - 0,0,114,253,0,0,0,114,7,0,0,0,114,7,0,0, - 0,114,7,0,0,0,114,8,0,0,0,114,34,1,0,0, - 61,4,0,0,115,10,0,0,0,8,0,4,2,8,2,8, - 5,18,5,114,34,1,0,0,99,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,2,0,0,0,64,0,0, - 0,115,32,0,0,0,101,0,90,1,100,0,90,2,100,1, - 90,3,100,2,100,3,132,0,90,4,100,4,100,5,132,0, - 90,5,100,6,83,0,41,7,218,20,83,111,117,114,99,101, - 108,101,115,115,70,105,108,101,76,111,97,100,101,114,122,45, - 76,111,97,100,101,114,32,119,104,105,99,104,32,104,97,110, - 100,108,101,115,32,115,111,117,114,99,101,108,101,115,115,32, - 102,105,108,101,32,105,109,112,111,114,116,115,46,99,2,0, - 0,0,0,0,0,0,0,0,0,0,5,0,0,0,5,0, - 0,0,67,0,0,0,115,68,0,0,0,124,0,160,0,124, - 1,161,1,125,2,124,0,160,1,124,2,161,1,125,3,124, - 1,124,2,100,1,156,2,125,4,116,2,124,3,124,1,124, - 4,131,3,1,0,116,3,116,4,124,3,131,1,100,2,100, - 0,133,2,25,0,124,1,124,2,100,3,141,3,83,0,41, - 4,78,114,183,0,0,0,114,169,0,0,0,41,2,114,141, - 0,0,0,114,132,0,0,0,41,5,114,203,0,0,0,114, - 255,0,0,0,114,176,0,0,0,114,189,0,0,0,114,7, - 1,0,0,41,5,114,143,0,0,0,114,163,0,0,0,114, - 65,0,0,0,114,41,0,0,0,114,175,0,0,0,114,7, - 0,0,0,114,7,0,0,0,114,8,0,0,0,114,241,0, - 0,0,110,4,0,0,115,22,0,0,0,10,1,10,1,2, - 4,2,1,6,254,12,4,2,1,14,1,2,1,2,1,6, - 253,122,29,83,111,117,114,99,101,108,101,115,115,70,105,108, - 101,76,111,97,100,101,114,46,103,101,116,95,99,111,100,101, - 99,2,0,0,0,0,0,0,0,0,0,0,0,2,0,0, - 0,1,0,0,0,67,0,0,0,114,23,0,0,0,41,2, - 122,39,82,101,116,117,114,110,32,78,111,110,101,32,97,115, - 32,116,104,101,114,101,32,105,115,32,110,111,32,115,111,117, - 114,99,101,32,99,111,100,101,46,78,114,7,0,0,0,114, - 247,0,0,0,114,7,0,0,0,114,7,0,0,0,114,8, - 0,0,0,114,1,1,0,0,126,4,0,0,114,24,0,0, - 0,122,31,83,111,117,114,99,101,108,101,115,115,70,105,108, - 101,76,111,97,100,101,114,46,103,101,116,95,115,111,117,114, - 99,101,78,41,6,114,150,0,0,0,114,149,0,0,0,114, - 151,0,0,0,114,152,0,0,0,114,241,0,0,0,114,1, - 1,0,0,114,7,0,0,0,114,7,0,0,0,114,7,0, - 0,0,114,8,0,0,0,114,41,1,0,0,106,4,0,0, - 115,8,0,0,0,8,0,4,2,8,2,12,16,114,41,1, - 0,0,99,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,3,0,0,0,64,0,0,0,115,92,0,0,0, - 101,0,90,1,100,0,90,2,100,1,90,3,100,2,100,3, - 132,0,90,4,100,4,100,5,132,0,90,5,100,6,100,7, - 132,0,90,6,100,8,100,9,132,0,90,7,100,10,100,11, - 132,0,90,8,100,12,100,13,132,0,90,9,100,14,100,15, - 132,0,90,10,100,16,100,17,132,0,90,11,101,12,100,18, - 100,19,132,0,131,1,90,13,100,20,83,0,41,21,114,30, - 1,0,0,122,93,76,111,97,100,101,114,32,102,111,114,32, - 101,120,116,101,110,115,105,111,110,32,109,111,100,117,108,101, - 115,46,10,10,32,32,32,32,84,104,101,32,99,111,110,115, - 116,114,117,99,116,111,114,32,105,115,32,100,101,115,105,103, - 110,101,100,32,116,111,32,119,111,114,107,32,119,105,116,104, - 32,70,105,108,101,70,105,110,100,101,114,46,10,10,32,32, - 32,32,99,3,0,0,0,0,0,0,0,0,0,0,0,3, - 0,0,0,2,0,0,0,67,0,0,0,115,16,0,0,0, - 124,1,124,0,95,0,124,2,124,0,95,1,100,0,83,0, - 114,69,0,0,0,114,183,0,0,0,41,3,114,143,0,0, - 0,114,141,0,0,0,114,65,0,0,0,114,7,0,0,0, - 114,7,0,0,0,114,8,0,0,0,114,236,0,0,0,139, - 4,0,0,115,4,0,0,0,6,1,10,1,122,28,69,120, - 116,101,110,115,105,111,110,70,105,108,101,76,111,97,100,101, - 114,46,95,95,105,110,105,116,95,95,99,2,0,0,0,0, - 0,0,0,0,0,0,0,2,0,0,0,2,0,0,0,67, - 0,0,0,114,12,1,0,0,114,69,0,0,0,114,13,1, - 0,0,114,15,1,0,0,114,7,0,0,0,114,7,0,0, - 0,114,8,0,0,0,114,16,1,0,0,143,4,0,0,114, - 17,1,0,0,122,26,69,120,116,101,110,115,105,111,110,70, - 105,108,101,76,111,97,100,101,114,46,95,95,101,113,95,95, - 99,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0, - 0,3,0,0,0,67,0,0,0,114,18,1,0,0,114,69, - 0,0,0,114,19,1,0,0,114,21,1,0,0,114,7,0, - 0,0,114,7,0,0,0,114,8,0,0,0,114,22,1,0, - 0,147,4,0,0,114,23,1,0,0,122,28,69,120,116,101, - 110,115,105,111,110,70,105,108,101,76,111,97,100,101,114,46, - 95,95,104,97,115,104,95,95,99,2,0,0,0,0,0,0, - 0,0,0,0,0,3,0,0,0,5,0,0,0,67,0,0, - 0,115,36,0,0,0,116,0,160,1,116,2,106,3,124,1, - 161,2,125,2,116,0,160,4,100,1,124,1,106,5,124,0, - 106,6,161,3,1,0,124,2,83,0,41,2,122,38,67,114, - 101,97,116,101,32,97,110,32,117,110,105,116,105,97,108,105, - 122,101,100,32,101,120,116,101,110,115,105,111,110,32,109,111, - 100,117,108,101,122,38,101,120,116,101,110,115,105,111,110,32, - 109,111,100,117,108,101,32,123,33,114,125,32,108,111,97,100, - 101,100,32,102,114,111,109,32,123,33,114,125,41,7,114,159, - 0,0,0,114,242,0,0,0,114,187,0,0,0,90,14,99, - 114,101,97,116,101,95,100,121,110,97,109,105,99,114,173,0, - 0,0,114,141,0,0,0,114,65,0,0,0,41,3,114,143, - 0,0,0,114,210,0,0,0,114,244,0,0,0,114,7,0, - 0,0,114,7,0,0,0,114,8,0,0,0,114,239,0,0, - 0,150,4,0,0,115,14,0,0,0,4,2,6,1,4,255, - 6,2,8,1,4,255,4,2,122,33,69,120,116,101,110,115, - 105,111,110,70,105,108,101,76,111,97,100,101,114,46,99,114, - 101,97,116,101,95,109,111,100,117,108,101,99,2,0,0,0, - 0,0,0,0,0,0,0,0,2,0,0,0,5,0,0,0, - 67,0,0,0,115,36,0,0,0,116,0,160,1,116,2,106, - 3,124,1,161,2,1,0,116,0,160,4,100,1,124,0,106, - 5,124,0,106,6,161,3,1,0,100,2,83,0,41,3,122, - 30,73,110,105,116,105,97,108,105,122,101,32,97,110,32,101, - 120,116,101,110,115,105,111,110,32,109,111,100,117,108,101,122, - 40,101,120,116,101,110,115,105,111,110,32,109,111,100,117,108, - 101,32,123,33,114,125,32,101,120,101,99,117,116,101,100,32, - 102,114,111,109,32,123,33,114,125,78,41,7,114,159,0,0, - 0,114,242,0,0,0,114,187,0,0,0,90,12,101,120,101, - 99,95,100,121,110,97,109,105,99,114,173,0,0,0,114,141, - 0,0,0,114,65,0,0,0,169,2,114,143,0,0,0,114, - 244,0,0,0,114,7,0,0,0,114,7,0,0,0,114,8, - 0,0,0,114,245,0,0,0,158,4,0,0,115,8,0,0, - 0,14,2,6,1,8,1,8,255,122,31,69,120,116,101,110, - 115,105,111,110,70,105,108,101,76,111,97,100,101,114,46,101, - 120,101,99,95,109,111,100,117,108,101,99,2,0,0,0,0, - 0,0,0,0,0,0,0,2,0,0,0,4,0,0,0,3, - 0,0,0,115,36,0,0,0,116,0,124,0,106,1,131,1, - 100,1,25,0,137,0,116,2,135,0,102,1,100,2,100,3, - 132,8,116,3,68,0,131,1,131,1,83,0,41,4,122,49, - 82,101,116,117,114,110,32,84,114,117,101,32,105,102,32,116, - 104,101,32,101,120,116,101,110,115,105,111,110,32,109,111,100, - 117,108,101,32,105,115,32,97,32,112,97,99,107,97,103,101, - 46,114,3,0,0,0,99,1,0,0,0,0,0,0,0,0, - 0,0,0,2,0,0,0,4,0,0,0,51,0,0,0,115, - 28,0,0,0,129,0,124,0,93,9,125,1,136,0,100,0, - 124,1,23,0,107,2,86,0,1,0,113,2,100,1,83,0, - 41,2,114,236,0,0,0,78,114,7,0,0,0,169,2,114, - 5,0,0,0,218,6,115,117,102,102,105,120,169,1,90,9, - 102,105,108,101,95,110,97,109,101,114,7,0,0,0,114,8, - 0,0,0,114,9,0,0,0,167,4,0,0,115,8,0,0, - 0,2,128,4,0,2,1,20,255,122,49,69,120,116,101,110, - 115,105,111,110,70,105,108,101,76,111,97,100,101,114,46,105, - 115,95,112,97,99,107,97,103,101,46,60,108,111,99,97,108, - 115,62,46,60,103,101,110,101,120,112,114,62,41,4,114,74, - 0,0,0,114,65,0,0,0,218,3,97,110,121,114,232,0, - 0,0,114,247,0,0,0,114,7,0,0,0,114,45,1,0, - 0,114,8,0,0,0,114,206,0,0,0,164,4,0,0,115, - 8,0,0,0,14,2,12,1,2,1,8,255,122,30,69,120, - 116,101,110,115,105,111,110,70,105,108,101,76,111,97,100,101, - 114,46,105,115,95,112,97,99,107,97,103,101,99,2,0,0, - 0,0,0,0,0,0,0,0,0,2,0,0,0,1,0,0, - 0,67,0,0,0,114,23,0,0,0,41,2,122,63,82,101, - 116,117,114,110,32,78,111,110,101,32,97,115,32,97,110,32, - 101,120,116,101,110,115,105,111,110,32,109,111,100,117,108,101, - 32,99,97,110,110,111,116,32,99,114,101,97,116,101,32,97, - 32,99,111,100,101,32,111,98,106,101,99,116,46,78,114,7, - 0,0,0,114,247,0,0,0,114,7,0,0,0,114,7,0, - 0,0,114,8,0,0,0,114,241,0,0,0,170,4,0,0, - 114,24,0,0,0,122,28,69,120,116,101,110,115,105,111,110, - 70,105,108,101,76,111,97,100,101,114,46,103,101,116,95,99, - 111,100,101,99,2,0,0,0,0,0,0,0,0,0,0,0, - 2,0,0,0,1,0,0,0,67,0,0,0,114,23,0,0, - 0,41,2,122,53,82,101,116,117,114,110,32,78,111,110,101, - 32,97,115,32,101,120,116,101,110,115,105,111,110,32,109,111, - 100,117,108,101,115,32,104,97,118,101,32,110,111,32,115,111, - 117,114,99,101,32,99,111,100,101,46,78,114,7,0,0,0, - 114,247,0,0,0,114,7,0,0,0,114,7,0,0,0,114, - 8,0,0,0,114,1,1,0,0,174,4,0,0,114,24,0, - 0,0,122,30,69,120,116,101,110,115,105,111,110,70,105,108, - 101,76,111,97,100,101,114,46,103,101,116,95,115,111,117,114, - 99,101,99,2,0,0,0,0,0,0,0,0,0,0,0,2, - 0,0,0,1,0,0,0,67,0,0,0,114,26,1,0,0, - 114,27,1,0,0,114,71,0,0,0,114,247,0,0,0,114, - 7,0,0,0,114,7,0,0,0,114,8,0,0,0,114,203, - 0,0,0,178,4,0,0,114,28,1,0,0,122,32,69,120, - 116,101,110,115,105,111,110,70,105,108,101,76,111,97,100,101, - 114,46,103,101,116,95,102,105,108,101,110,97,109,101,78,41, - 14,114,150,0,0,0,114,149,0,0,0,114,151,0,0,0, - 114,152,0,0,0,114,236,0,0,0,114,16,1,0,0,114, - 22,1,0,0,114,239,0,0,0,114,245,0,0,0,114,206, - 0,0,0,114,241,0,0,0,114,1,1,0,0,114,160,0, - 0,0,114,203,0,0,0,114,7,0,0,0,114,7,0,0, - 0,114,7,0,0,0,114,8,0,0,0,114,30,1,0,0, - 131,4,0,0,115,24,0,0,0,8,0,4,2,8,6,8, - 4,8,4,8,3,8,8,8,6,8,6,8,4,2,4,14, - 1,114,30,1,0,0,99,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,2,0,0,0,64,0,0,0,115, - 108,0,0,0,101,0,90,1,100,0,90,2,100,1,90,3, - 100,2,90,4,100,3,100,4,132,0,90,5,100,5,100,6, - 132,0,90,6,100,7,100,8,132,0,90,7,100,9,100,10, - 132,0,90,8,100,11,100,12,132,0,90,9,100,13,100,14, - 132,0,90,10,100,15,100,16,132,0,90,11,100,17,100,18, - 132,0,90,12,100,19,100,20,132,0,90,13,100,21,100,22, - 132,0,90,14,100,23,100,24,132,0,90,15,100,25,83,0, - 41,26,218,14,95,78,97,109,101,115,112,97,99,101,80,97, - 116,104,97,38,1,0,0,82,101,112,114,101,115,101,110,116, - 115,32,97,32,110,97,109,101,115,112,97,99,101,32,112,97, - 99,107,97,103,101,39,115,32,112,97,116,104,46,32,32,73, - 116,32,117,115,101,115,32,116,104,101,32,109,111,100,117,108, - 101,32,110,97,109,101,10,32,32,32,32,116,111,32,102,105, - 110,100,32,105,116,115,32,112,97,114,101,110,116,32,109,111, - 100,117,108,101,44,32,97,110,100,32,102,114,111,109,32,116, - 104,101,114,101,32,105,116,32,108,111,111,107,115,32,117,112, - 32,116,104,101,32,112,97,114,101,110,116,39,115,10,32,32, - 32,32,95,95,112,97,116,104,95,95,46,32,32,87,104,101, - 110,32,116,104,105,115,32,99,104,97,110,103,101,115,44,32, - 116,104,101,32,109,111,100,117,108,101,39,115,32,111,119,110, - 32,112,97,116,104,32,105,115,32,114,101,99,111,109,112,117, - 116,101,100,44,10,32,32,32,32,117,115,105,110,103,32,112, - 97,116,104,95,102,105,110,100,101,114,46,32,32,70,111,114, - 32,116,111,112,45,108,101,118,101,108,32,109,111,100,117,108, - 101,115,44,32,116,104,101,32,112,97,114,101,110,116,32,109, - 111,100,117,108,101,39,115,32,112,97,116,104,10,32,32,32, - 32,105,115,32,115,121,115,46,112,97,116,104,46,114,0,0, - 0,0,99,4,0,0,0,0,0,0,0,0,0,0,0,4, - 0,0,0,3,0,0,0,67,0,0,0,115,44,0,0,0, - 124,1,124,0,95,0,124,2,124,0,95,1,116,2,124,0, - 160,3,161,0,131,1,124,0,95,4,124,0,106,5,124,0, - 95,6,124,3,124,0,95,7,100,0,83,0,114,69,0,0, - 0,41,8,218,5,95,110,97,109,101,218,5,95,112,97,116, - 104,114,136,0,0,0,218,16,95,103,101,116,95,112,97,114, - 101,110,116,95,112,97,116,104,218,17,95,108,97,115,116,95, - 112,97,114,101,110,116,95,112,97,116,104,218,6,95,101,112, - 111,99,104,218,11,95,108,97,115,116,95,101,112,111,99,104, - 218,12,95,112,97,116,104,95,102,105,110,100,101,114,169,4, - 114,143,0,0,0,114,141,0,0,0,114,65,0,0,0,90, - 11,112,97,116,104,95,102,105,110,100,101,114,114,7,0,0, - 0,114,7,0,0,0,114,8,0,0,0,114,236,0,0,0, - 195,4,0,0,115,10,0,0,0,6,1,6,1,14,1,8, - 1,10,1,122,23,95,78,97,109,101,115,112,97,99,101,80, - 97,116,104,46,95,95,105,110,105,116,95,95,99,1,0,0, - 0,0,0,0,0,0,0,0,0,4,0,0,0,3,0,0, - 0,67,0,0,0,115,38,0,0,0,124,0,106,0,160,1, - 100,1,161,1,92,3,125,1,125,2,125,3,124,2,100,2, - 107,2,114,15,100,3,83,0,124,1,100,4,102,2,83,0, - 41,5,122,62,82,101,116,117,114,110,115,32,97,32,116,117, - 112,108,101,32,111,102,32,40,112,97,114,101,110,116,45,109, - 111,100,117,108,101,45,110,97,109,101,44,32,112,97,114,101, - 110,116,45,112,97,116,104,45,97,116,116,114,45,110,97,109, - 101,41,114,97,0,0,0,114,10,0,0,0,41,2,114,15, - 0,0,0,114,65,0,0,0,90,8,95,95,112,97,116,104, - 95,95,41,2,114,48,1,0,0,114,104,0,0,0,41,4, - 114,143,0,0,0,114,40,1,0,0,218,3,100,111,116,90, - 2,109,101,114,7,0,0,0,114,7,0,0,0,114,8,0, - 0,0,218,23,95,102,105,110,100,95,112,97,114,101,110,116, - 95,112,97,116,104,95,110,97,109,101,115,202,4,0,0,115, - 8,0,0,0,18,2,8,1,4,2,8,3,122,38,95,78, - 97,109,101,115,112,97,99,101,80,97,116,104,46,95,102,105, - 110,100,95,112,97,114,101,110,116,95,112,97,116,104,95,110, - 97,109,101,115,99,1,0,0,0,0,0,0,0,0,0,0, - 0,3,0,0,0,3,0,0,0,67,0,0,0,115,28,0, - 0,0,124,0,160,0,161,0,92,2,125,1,125,2,116,1, - 116,2,106,3,124,1,25,0,124,2,131,2,83,0,114,69, - 0,0,0,41,4,114,57,1,0,0,114,155,0,0,0,114, - 15,0,0,0,218,7,109,111,100,117,108,101,115,41,3,114, - 143,0,0,0,90,18,112,97,114,101,110,116,95,109,111,100, - 117,108,101,95,110,97,109,101,90,14,112,97,116,104,95,97, - 116,116,114,95,110,97,109,101,114,7,0,0,0,114,7,0, - 0,0,114,8,0,0,0,114,50,1,0,0,212,4,0,0, - 115,4,0,0,0,12,1,16,1,122,31,95,78,97,109,101, - 115,112,97,99,101,80,97,116,104,46,95,103,101,116,95,112, - 97,114,101,110,116,95,112,97,116,104,99,1,0,0,0,0, - 0,0,0,0,0,0,0,3,0,0,0,4,0,0,0,67, - 0,0,0,115,100,0,0,0,116,0,124,0,160,1,161,0, - 131,1,125,1,124,1,124,0,106,2,107,3,115,17,124,0, - 106,3,124,0,106,4,107,3,114,47,124,0,160,5,124,0, - 106,6,124,1,161,2,125,2,124,2,100,0,117,1,114,40, - 124,2,106,7,100,0,117,0,114,40,124,2,106,8,114,40, - 124,2,106,8,124,0,95,9,124,1,124,0,95,2,124,0, - 106,3,124,0,95,4,124,0,106,9,83,0,114,69,0,0, - 0,41,10,114,136,0,0,0,114,50,1,0,0,114,51,1, - 0,0,114,52,1,0,0,114,53,1,0,0,114,54,1,0, - 0,114,48,1,0,0,114,164,0,0,0,114,202,0,0,0, - 114,49,1,0,0,41,3,114,143,0,0,0,90,11,112,97, - 114,101,110,116,95,112,97,116,104,114,210,0,0,0,114,7, - 0,0,0,114,7,0,0,0,114,8,0,0,0,218,12,95, - 114,101,99,97,108,99,117,108,97,116,101,216,4,0,0,115, - 18,0,0,0,12,2,22,1,14,1,18,3,6,1,8,1, - 6,1,8,1,6,1,122,27,95,78,97,109,101,115,112,97, - 99,101,80,97,116,104,46,95,114,101,99,97,108,99,117,108, - 97,116,101,99,1,0,0,0,0,0,0,0,0,0,0,0, - 1,0,0,0,3,0,0,0,67,0,0,0,243,12,0,0, - 0,116,0,124,0,160,1,161,0,131,1,83,0,114,69,0, - 0,0,41,2,218,4,105,116,101,114,114,59,1,0,0,114, - 21,1,0,0,114,7,0,0,0,114,7,0,0,0,114,8, - 0,0,0,218,8,95,95,105,116,101,114,95,95,230,4,0, - 0,243,2,0,0,0,12,1,122,23,95,78,97,109,101,115, - 112,97,99,101,80,97,116,104,46,95,95,105,116,101,114,95, - 95,99,2,0,0,0,0,0,0,0,0,0,0,0,2,0, - 0,0,2,0,0,0,67,0,0,0,115,12,0,0,0,124, - 0,160,0,161,0,124,1,25,0,83,0,114,69,0,0,0, - 169,1,114,59,1,0,0,41,2,114,143,0,0,0,218,5, - 105,110,100,101,120,114,7,0,0,0,114,7,0,0,0,114, - 8,0,0,0,218,11,95,95,103,101,116,105,116,101,109,95, - 95,233,4,0,0,114,63,1,0,0,122,26,95,78,97,109, - 101,115,112,97,99,101,80,97,116,104,46,95,95,103,101,116, - 105,116,101,109,95,95,99,3,0,0,0,0,0,0,0,0, - 0,0,0,3,0,0,0,3,0,0,0,67,0,0,0,115, - 14,0,0,0,124,2,124,0,106,0,124,1,60,0,100,0, - 83,0,114,69,0,0,0,41,1,114,49,1,0,0,41,3, - 114,143,0,0,0,114,65,1,0,0,114,65,0,0,0,114, - 7,0,0,0,114,7,0,0,0,114,8,0,0,0,218,11, - 95,95,115,101,116,105,116,101,109,95,95,236,4,0,0,115, - 2,0,0,0,14,1,122,26,95,78,97,109,101,115,112,97, - 99,101,80,97,116,104,46,95,95,115,101,116,105,116,101,109, - 95,95,99,1,0,0,0,0,0,0,0,0,0,0,0,1, - 0,0,0,3,0,0,0,67,0,0,0,114,60,1,0,0, - 114,69,0,0,0,41,2,114,4,0,0,0,114,59,1,0, - 0,114,21,1,0,0,114,7,0,0,0,114,7,0,0,0, - 114,8,0,0,0,218,7,95,95,108,101,110,95,95,239,4, - 0,0,114,63,1,0,0,122,22,95,78,97,109,101,115,112, - 97,99,101,80,97,116,104,46,95,95,108,101,110,95,95,99, - 1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0, - 3,0,0,0,67,0,0,0,243,12,0,0,0,100,1,160, - 0,124,0,106,1,161,1,83,0,41,2,78,122,20,95,78, - 97,109,101,115,112,97,99,101,80,97,116,104,40,123,33,114, - 125,41,41,2,114,89,0,0,0,114,49,1,0,0,114,21, - 1,0,0,114,7,0,0,0,114,7,0,0,0,114,8,0, - 0,0,218,8,95,95,114,101,112,114,95,95,242,4,0,0, - 114,63,1,0,0,122,23,95,78,97,109,101,115,112,97,99, - 101,80,97,116,104,46,95,95,114,101,112,114,95,95,99,2, - 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,3, - 0,0,0,67,0,0,0,115,12,0,0,0,124,1,124,0, - 160,0,161,0,118,0,83,0,114,69,0,0,0,114,64,1, - 0,0,169,2,114,143,0,0,0,218,4,105,116,101,109,114, - 7,0,0,0,114,7,0,0,0,114,8,0,0,0,218,12, - 95,95,99,111,110,116,97,105,110,115,95,95,245,4,0,0, - 114,63,1,0,0,122,27,95,78,97,109,101,115,112,97,99, - 101,80,97,116,104,46,95,95,99,111,110,116,97,105,110,115, - 95,95,99,2,0,0,0,0,0,0,0,0,0,0,0,2, - 0,0,0,3,0,0,0,67,0,0,0,115,16,0,0,0, - 124,0,106,0,160,1,124,1,161,1,1,0,100,0,83,0, - 114,69,0,0,0,41,2,114,49,1,0,0,114,61,0,0, - 0,114,71,1,0,0,114,7,0,0,0,114,7,0,0,0, - 114,8,0,0,0,114,61,0,0,0,248,4,0,0,243,2, - 0,0,0,16,1,122,21,95,78,97,109,101,115,112,97,99, - 101,80,97,116,104,46,97,112,112,101,110,100,78,41,16,114, - 150,0,0,0,114,149,0,0,0,114,151,0,0,0,114,152, - 0,0,0,114,52,1,0,0,114,236,0,0,0,114,57,1, - 0,0,114,50,1,0,0,114,59,1,0,0,114,62,1,0, - 0,114,66,1,0,0,114,67,1,0,0,114,68,1,0,0, - 114,70,1,0,0,114,73,1,0,0,114,61,0,0,0,114, - 7,0,0,0,114,7,0,0,0,114,7,0,0,0,114,8, - 0,0,0,114,47,1,0,0,184,4,0,0,115,28,0,0, - 0,8,0,4,1,4,8,8,2,8,7,8,10,8,4,8, - 14,8,3,8,3,8,3,8,3,8,3,12,3,114,47,1, - 0,0,99,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,3,0,0,0,64,0,0,0,115,88,0,0,0, - 101,0,90,1,100,0,90,2,100,1,100,2,132,0,90,3, - 101,4,100,3,100,4,132,0,131,1,90,5,100,5,100,6, - 132,0,90,6,100,7,100,8,132,0,90,7,100,9,100,10, - 132,0,90,8,100,11,100,12,132,0,90,9,100,13,100,14, - 132,0,90,10,100,15,100,16,132,0,90,11,100,17,100,18, - 132,0,90,12,100,19,83,0,41,20,218,16,95,78,97,109, - 101,115,112,97,99,101,76,111,97,100,101,114,99,4,0,0, - 0,0,0,0,0,0,0,0,0,4,0,0,0,4,0,0, - 0,67,0,0,0,115,18,0,0,0,116,0,124,1,124,2, - 124,3,131,3,124,0,95,1,100,0,83,0,114,69,0,0, - 0,41,2,114,47,1,0,0,114,49,1,0,0,114,55,1, - 0,0,114,7,0,0,0,114,7,0,0,0,114,8,0,0, - 0,114,236,0,0,0,254,4,0,0,115,2,0,0,0,18, - 1,122,25,95,78,97,109,101,115,112,97,99,101,76,111,97, - 100,101,114,46,95,95,105,110,105,116,95,95,99,1,0,0, - 0,0,0,0,0,0,0,0,0,1,0,0,0,4,0,0, - 0,67,0,0,0,115,24,0,0,0,116,0,160,1,100,1, - 116,2,161,2,1,0,100,2,160,3,124,0,106,4,161,1, - 83,0,41,3,122,115,82,101,116,117,114,110,32,114,101,112, - 114,32,102,111,114,32,116,104,101,32,109,111,100,117,108,101, - 46,10,10,32,32,32,32,32,32,32,32,84,104,101,32,109, - 101,116,104,111,100,32,105,115,32,100,101,112,114,101,99,97, - 116,101,100,46,32,32,84,104,101,32,105,109,112,111,114,116, - 32,109,97,99,104,105,110,101,114,121,32,100,111,101,115,32, - 116,104,101,32,106,111,98,32,105,116,115,101,108,102,46,10, - 10,32,32,32,32,32,32,32,32,122,82,95,78,97,109,101, - 115,112,97,99,101,76,111,97,100,101,114,46,109,111,100,117, - 108,101,95,114,101,112,114,40,41,32,105,115,32,100,101,112, - 114,101,99,97,116,101,100,32,97,110,100,32,115,108,97,116, - 101,100,32,102,111,114,32,114,101,109,111,118,97,108,32,105, - 110,32,80,121,116,104,111,110,32,51,46,49,50,122,25,60, - 109,111,100,117,108,101,32,123,33,114,125,32,40,110,97,109, - 101,115,112,97,99,101,41,62,41,5,114,99,0,0,0,114, - 100,0,0,0,114,101,0,0,0,114,89,0,0,0,114,150, - 0,0,0,41,1,114,244,0,0,0,114,7,0,0,0,114, - 7,0,0,0,114,8,0,0,0,218,11,109,111,100,117,108, - 101,95,114,101,112,114,1,5,0,0,115,8,0,0,0,6, - 7,2,1,4,255,12,2,122,28,95,78,97,109,101,115,112, - 97,99,101,76,111,97,100,101,114,46,109,111,100,117,108,101, - 95,114,101,112,114,99,2,0,0,0,0,0,0,0,0,0, - 0,0,2,0,0,0,1,0,0,0,67,0,0,0,114,23, - 0,0,0,41,2,78,84,114,7,0,0,0,114,247,0,0, - 0,114,7,0,0,0,114,7,0,0,0,114,8,0,0,0, - 114,206,0,0,0,12,5,0,0,243,2,0,0,0,4,1, - 122,27,95,78,97,109,101,115,112,97,99,101,76,111,97,100, - 101,114,46,105,115,95,112,97,99,107,97,103,101,99,2,0, - 0,0,0,0,0,0,0,0,0,0,2,0,0,0,1,0, - 0,0,67,0,0,0,114,23,0,0,0,41,2,78,114,10, - 0,0,0,114,7,0,0,0,114,247,0,0,0,114,7,0, - 0,0,114,7,0,0,0,114,8,0,0,0,114,1,1,0, - 0,15,5,0,0,114,77,1,0,0,122,27,95,78,97,109, - 101,115,112,97,99,101,76,111,97,100,101,114,46,103,101,116, - 95,115,111,117,114,99,101,99,2,0,0,0,0,0,0,0, - 0,0,0,0,2,0,0,0,6,0,0,0,67,0,0,0, - 115,16,0,0,0,116,0,100,1,100,2,100,3,100,4,100, - 5,141,4,83,0,41,6,78,114,10,0,0,0,122,8,60, - 115,116,114,105,110,103,62,114,243,0,0,0,84,41,1,114, - 3,1,0,0,41,1,114,4,1,0,0,114,247,0,0,0, - 114,7,0,0,0,114,7,0,0,0,114,8,0,0,0,114, - 241,0,0,0,18,5,0,0,114,74,1,0,0,122,25,95, - 78,97,109,101,115,112,97,99,101,76,111,97,100,101,114,46, - 103,101,116,95,99,111,100,101,99,2,0,0,0,0,0,0, - 0,0,0,0,0,2,0,0,0,1,0,0,0,67,0,0, - 0,114,23,0,0,0,114,237,0,0,0,114,7,0,0,0, - 114,238,0,0,0,114,7,0,0,0,114,7,0,0,0,114, - 8,0,0,0,114,239,0,0,0,21,5,0,0,114,240,0, - 0,0,122,30,95,78,97,109,101,115,112,97,99,101,76,111, - 97,100,101,114,46,99,114,101,97,116,101,95,109,111,100,117, - 108,101,99,2,0,0,0,0,0,0,0,0,0,0,0,2, - 0,0,0,1,0,0,0,67,0,0,0,115,4,0,0,0, - 100,0,83,0,114,69,0,0,0,114,7,0,0,0,114,42, - 1,0,0,114,7,0,0,0,114,7,0,0,0,114,8,0, - 0,0,114,245,0,0,0,24,5,0,0,114,77,1,0,0, - 122,28,95,78,97,109,101,115,112,97,99,101,76,111,97,100, - 101,114,46,101,120,101,99,95,109,111,100,117,108,101,99,2, - 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,4, - 0,0,0,67,0,0,0,115,26,0,0,0,116,0,160,1, - 100,1,124,0,106,2,161,2,1,0,116,0,160,3,124,0, - 124,1,161,2,83,0,41,2,122,98,76,111,97,100,32,97, - 32,110,97,109,101,115,112,97,99,101,32,109,111,100,117,108, - 101,46,10,10,32,32,32,32,32,32,32,32,84,104,105,115, - 32,109,101,116,104,111,100,32,105,115,32,100,101,112,114,101, - 99,97,116,101,100,46,32,32,85,115,101,32,101,120,101,99, - 95,109,111,100,117,108,101,40,41,32,105,110,115,116,101,97, - 100,46,10,10,32,32,32,32,32,32,32,32,122,38,110,97, - 109,101,115,112,97,99,101,32,109,111,100,117,108,101,32,108, - 111,97,100,101,100,32,119,105,116,104,32,112,97,116,104,32, - 123,33,114,125,41,4,114,159,0,0,0,114,173,0,0,0, - 114,49,1,0,0,114,246,0,0,0,114,247,0,0,0,114, - 7,0,0,0,114,7,0,0,0,114,8,0,0,0,114,248, - 0,0,0,27,5,0,0,115,8,0,0,0,6,7,4,1, - 4,255,12,3,122,28,95,78,97,109,101,115,112,97,99,101, - 76,111,97,100,101,114,46,108,111,97,100,95,109,111,100,117, - 108,101,99,2,0,0,0,0,0,0,0,0,0,0,0,3, - 0,0,0,2,0,0,0,67,0,0,0,115,22,0,0,0, - 100,1,100,2,108,0,109,1,125,2,1,0,124,2,124,0, - 106,2,131,1,83,0,41,3,78,114,0,0,0,0,41,1, - 218,15,78,97,109,101,115,112,97,99,101,82,101,97,100,101, - 114,41,3,114,32,1,0,0,114,78,1,0,0,114,49,1, - 0,0,41,3,114,143,0,0,0,114,244,0,0,0,114,78, - 1,0,0,114,7,0,0,0,114,7,0,0,0,114,8,0, - 0,0,114,33,1,0,0,39,5,0,0,115,4,0,0,0, - 12,1,10,1,122,36,95,78,97,109,101,115,112,97,99,101, - 76,111,97,100,101,114,46,103,101,116,95,114,101,115,111,117, - 114,99,101,95,114,101,97,100,101,114,78,41,13,114,150,0, - 0,0,114,149,0,0,0,114,151,0,0,0,114,236,0,0, - 0,114,233,0,0,0,114,76,1,0,0,114,206,0,0,0, - 114,1,1,0,0,114,241,0,0,0,114,239,0,0,0,114, - 245,0,0,0,114,248,0,0,0,114,33,1,0,0,114,7, - 0,0,0,114,7,0,0,0,114,7,0,0,0,114,8,0, - 0,0,114,75,1,0,0,253,4,0,0,115,22,0,0,0, - 8,0,8,1,2,3,10,1,8,10,8,3,8,3,8,3, - 8,3,8,3,12,12,114,75,1,0,0,99,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0, - 64,0,0,0,115,118,0,0,0,101,0,90,1,100,0,90, - 2,100,1,90,3,101,4,100,2,100,3,132,0,131,1,90, - 5,101,4,100,4,100,5,132,0,131,1,90,6,101,7,100, - 6,100,7,132,0,131,1,90,8,101,7,100,8,100,9,132, - 0,131,1,90,9,101,7,100,19,100,11,100,12,132,1,131, - 1,90,10,101,7,100,20,100,13,100,14,132,1,131,1,90, - 11,101,7,100,19,100,15,100,16,132,1,131,1,90,12,101, - 4,100,17,100,18,132,0,131,1,90,13,100,10,83,0,41, - 21,218,10,80,97,116,104,70,105,110,100,101,114,122,62,77, - 101,116,97,32,112,97,116,104,32,102,105,110,100,101,114,32, - 102,111,114,32,115,121,115,46,112,97,116,104,32,97,110,100, - 32,112,97,99,107,97,103,101,32,95,95,112,97,116,104,95, - 95,32,97,116,116,114,105,98,117,116,101,115,46,99,0,0, - 0,0,0,0,0,0,0,0,0,0,2,0,0,0,4,0, - 0,0,67,0,0,0,115,78,0,0,0,116,0,116,1,106, - 2,160,3,161,0,131,1,68,0,93,22,92,2,125,0,125, - 1,124,1,100,1,117,0,114,20,116,1,106,2,124,0,61, - 0,113,7,116,4,124,1,100,2,131,2,114,29,124,1,160, - 5,161,0,1,0,113,7,116,6,4,0,106,7,100,3,55, - 0,2,0,95,7,100,1,83,0,41,4,122,125,67,97,108, - 108,32,116,104,101,32,105,110,118,97,108,105,100,97,116,101, - 95,99,97,99,104,101,115,40,41,32,109,101,116,104,111,100, - 32,111,110,32,97,108,108,32,112,97,116,104,32,101,110,116, - 114,121,32,102,105,110,100,101,114,115,10,32,32,32,32,32, - 32,32,32,115,116,111,114,101,100,32,105,110,32,115,121,115, - 46,112,97,116,104,95,105,109,112,111,114,116,101,114,95,99, - 97,99,104,101,115,32,40,119,104,101,114,101,32,105,109,112, - 108,101,109,101,110,116,101,100,41,46,78,218,17,105,110,118, - 97,108,105,100,97,116,101,95,99,97,99,104,101,115,114,3, - 0,0,0,41,8,218,4,108,105,115,116,114,15,0,0,0, - 218,19,112,97,116,104,95,105,109,112,111,114,116,101,114,95, - 99,97,99,104,101,218,5,105,116,101,109,115,114,153,0,0, - 0,114,80,1,0,0,114,47,1,0,0,114,52,1,0,0, - 41,2,114,141,0,0,0,218,6,102,105,110,100,101,114,114, - 7,0,0,0,114,7,0,0,0,114,8,0,0,0,114,80, - 1,0,0,50,5,0,0,115,14,0,0,0,22,4,8,1, - 10,1,10,1,8,1,2,128,18,3,122,28,80,97,116,104, - 70,105,110,100,101,114,46,105,110,118,97,108,105,100,97,116, - 101,95,99,97,99,104,101,115,99,1,0,0,0,0,0,0, - 0,0,0,0,0,2,0,0,0,9,0,0,0,67,0,0, - 0,115,76,0,0,0,116,0,106,1,100,1,117,1,114,14, - 116,0,106,1,115,14,116,2,160,3,100,2,116,4,161,2, - 1,0,116,0,106,1,68,0,93,18,125,1,122,7,124,1, - 124,0,131,1,87,0,2,0,1,0,83,0,4,0,116,5, - 121,35,1,0,1,0,1,0,89,0,113,17,119,0,100,1, - 83,0,41,3,122,46,83,101,97,114,99,104,32,115,121,115, - 46,112,97,116,104,95,104,111,111,107,115,32,102,111,114,32, - 97,32,102,105,110,100,101,114,32,102,111,114,32,39,112,97, - 116,104,39,46,78,122,23,115,121,115,46,112,97,116,104,95, - 104,111,111,107,115,32,105,115,32,101,109,112,116,121,41,6, - 114,15,0,0,0,218,10,112,97,116,104,95,104,111,111,107, - 115,114,99,0,0,0,114,100,0,0,0,114,162,0,0,0, - 114,142,0,0,0,41,2,114,65,0,0,0,90,4,104,111, - 111,107,114,7,0,0,0,114,7,0,0,0,114,8,0,0, - 0,218,11,95,112,97,116,104,95,104,111,111,107,115,63,5, - 0,0,115,18,0,0,0,16,3,12,1,10,1,2,1,14, - 1,12,1,4,1,2,255,4,3,122,22,80,97,116,104,70, - 105,110,100,101,114,46,95,112,97,116,104,95,104,111,111,107, - 115,99,2,0,0,0,0,0,0,0,0,0,0,0,3,0, - 0,0,8,0,0,0,67,0,0,0,115,100,0,0,0,124, - 1,100,1,107,2,114,21,122,6,116,0,160,1,161,0,125, - 1,87,0,110,10,4,0,116,2,121,20,1,0,1,0,1, - 0,89,0,100,2,83,0,119,0,122,8,116,3,106,4,124, - 1,25,0,125,2,87,0,124,2,83,0,4,0,116,5,121, - 49,1,0,1,0,1,0,124,0,160,6,124,1,161,1,125, - 2,124,2,116,3,106,4,124,1,60,0,89,0,124,2,83, - 0,119,0,41,3,122,210,71,101,116,32,116,104,101,32,102, - 105,110,100,101,114,32,102,111,114,32,116,104,101,32,112,97, - 116,104,32,101,110,116,114,121,32,102,114,111,109,32,115,121, - 115,46,112,97,116,104,95,105,109,112,111,114,116,101,114,95, - 99,97,99,104,101,46,10,10,32,32,32,32,32,32,32,32, - 73,102,32,116,104,101,32,112,97,116,104,32,101,110,116,114, - 121,32,105,115,32,110,111,116,32,105,110,32,116,104,101,32, - 99,97,99,104,101,44,32,102,105,110,100,32,116,104,101,32, - 97,112,112,114,111,112,114,105,97,116,101,32,102,105,110,100, - 101,114,10,32,32,32,32,32,32,32,32,97,110,100,32,99, - 97,99,104,101,32,105,116,46,32,73,102,32,110,111,32,102, - 105,110,100,101,114,32,105,115,32,97,118,97,105,108,97,98, - 108,101,44,32,115,116,111,114,101,32,78,111,110,101,46,10, - 10,32,32,32,32,32,32,32,32,114,10,0,0,0,78,41, - 7,114,18,0,0,0,114,82,0,0,0,218,17,70,105,108, - 101,78,111,116,70,111,117,110,100,69,114,114,111,114,114,15, - 0,0,0,114,82,1,0,0,218,8,75,101,121,69,114,114, - 111,114,114,86,1,0,0,41,3,114,221,0,0,0,114,65, - 0,0,0,114,84,1,0,0,114,7,0,0,0,114,7,0, - 0,0,114,8,0,0,0,218,20,95,112,97,116,104,95,105, - 109,112,111,114,116,101,114,95,99,97,99,104,101,76,5,0, - 0,115,28,0,0,0,8,8,2,1,12,1,12,1,6,3, - 2,253,2,4,12,1,4,4,12,253,10,1,12,1,4,1, - 2,253,122,31,80,97,116,104,70,105,110,100,101,114,46,95, - 112,97,116,104,95,105,109,112,111,114,116,101,114,95,99,97, - 99,104,101,99,3,0,0,0,0,0,0,0,0,0,0,0, - 7,0,0,0,4,0,0,0,67,0,0,0,115,138,0,0, - 0,116,0,124,2,100,1,131,2,114,27,116,1,160,2,124, - 2,161,1,155,0,100,2,157,2,125,3,116,3,160,4,124, - 3,116,5,161,2,1,0,124,2,160,6,124,1,161,1,92, - 2,125,4,125,5,110,21,116,1,160,2,124,2,161,1,155, - 0,100,3,157,2,125,3,116,3,160,4,124,3,116,5,161, - 2,1,0,124,2,160,7,124,1,161,1,125,4,103,0,125, - 5,124,4,100,0,117,1,114,58,116,1,160,8,124,1,124, - 4,161,2,83,0,116,1,160,9,124,1,100,0,161,2,125, - 6,124,5,124,6,95,10,124,6,83,0,41,4,78,114,161, - 0,0,0,122,53,46,102,105,110,100,95,115,112,101,99,40, - 41,32,110,111,116,32,102,111,117,110,100,59,32,102,97,108, - 108,105,110,103,32,98,97,99,107,32,116,111,32,102,105,110, - 100,95,108,111,97,100,101,114,40,41,122,53,46,102,105,110, - 100,95,115,112,101,99,40,41,32,110,111,116,32,102,111,117, - 110,100,59,32,102,97,108,108,105,110,103,32,98,97,99,107, - 32,116,111,32,102,105,110,100,95,109,111,100,117,108,101,40, - 41,41,11,114,153,0,0,0,114,159,0,0,0,90,12,95, - 111,98,106,101,99,116,95,110,97,109,101,114,99,0,0,0, - 114,100,0,0,0,114,162,0,0,0,114,161,0,0,0,114, - 229,0,0,0,114,224,0,0,0,114,207,0,0,0,114,202, - 0,0,0,41,7,114,221,0,0,0,114,163,0,0,0,114, - 84,1,0,0,114,166,0,0,0,114,164,0,0,0,114,165, - 0,0,0,114,210,0,0,0,114,7,0,0,0,114,7,0, - 0,0,114,8,0,0,0,218,16,95,108,101,103,97,99,121, - 95,103,101,116,95,115,112,101,99,98,5,0,0,115,26,0, - 0,0,10,4,16,1,12,2,16,1,16,2,12,2,10,1, - 4,1,8,1,12,1,12,1,6,1,4,1,122,27,80,97, - 116,104,70,105,110,100,101,114,46,95,108,101,103,97,99,121, - 95,103,101,116,95,115,112,101,99,78,99,4,0,0,0,0, - 0,0,0,0,0,0,0,9,0,0,0,5,0,0,0,67, - 0,0,0,115,166,0,0,0,103,0,125,4,124,2,68,0, - 93,67,125,5,116,0,124,5,116,1,116,2,102,2,131,2, - 115,14,113,4,124,0,160,3,124,5,161,1,125,6,124,6, - 100,1,117,1,114,71,116,4,124,6,100,2,131,2,114,35, - 124,6,160,5,124,1,124,3,161,2,125,7,110,6,124,0, - 160,6,124,1,124,6,161,2,125,7,124,7,100,1,117,0, - 114,46,113,4,124,7,106,7,100,1,117,1,114,55,124,7, - 2,0,1,0,83,0,124,7,106,8,125,8,124,8,100,1, - 117,0,114,66,116,9,100,3,131,1,130,1,124,4,160,10, - 124,8,161,1,1,0,113,4,116,11,160,12,124,1,100,1, - 161,2,125,7,124,4,124,7,95,8,124,7,83,0,41,4, - 122,63,70,105,110,100,32,116,104,101,32,108,111,97,100,101, - 114,32,111,114,32,110,97,109,101,115,112,97,99,101,95,112, - 97,116,104,32,102,111,114,32,116,104,105,115,32,109,111,100, - 117,108,101,47,112,97,99,107,97,103,101,32,110,97,109,101, - 46,78,114,226,0,0,0,122,19,115,112,101,99,32,109,105, - 115,115,105,110,103,32,108,111,97,100,101,114,41,13,114,185, - 0,0,0,114,109,0,0,0,218,5,98,121,116,101,115,114, - 89,1,0,0,114,153,0,0,0,114,226,0,0,0,114,90, - 1,0,0,114,164,0,0,0,114,202,0,0,0,114,142,0, - 0,0,114,191,0,0,0,114,159,0,0,0,114,207,0,0, - 0,41,9,114,221,0,0,0,114,163,0,0,0,114,65,0, - 0,0,114,225,0,0,0,218,14,110,97,109,101,115,112,97, - 99,101,95,112,97,116,104,90,5,101,110,116,114,121,114,84, - 1,0,0,114,210,0,0,0,114,165,0,0,0,114,7,0, - 0,0,114,7,0,0,0,114,8,0,0,0,218,9,95,103, - 101,116,95,115,112,101,99,119,5,0,0,115,42,0,0,0, - 4,5,8,1,14,1,2,1,10,1,8,1,10,1,14,1, - 12,2,8,1,2,1,10,1,8,1,6,1,8,1,8,1, - 10,5,2,128,12,2,6,1,4,1,122,20,80,97,116,104, - 70,105,110,100,101,114,46,95,103,101,116,95,115,112,101,99, - 99,4,0,0,0,0,0,0,0,0,0,0,0,6,0,0, - 0,5,0,0,0,67,0,0,0,115,94,0,0,0,124,2, - 100,1,117,0,114,7,116,0,106,1,125,2,124,0,160,2, - 124,1,124,2,124,3,161,3,125,4,124,4,100,1,117,0, - 114,20,100,1,83,0,124,4,106,3,100,1,117,0,114,45, - 124,4,106,4,125,5,124,5,114,43,100,1,124,4,95,5, - 116,6,124,1,124,5,124,0,106,2,131,3,124,4,95,4, - 124,4,83,0,100,1,83,0,124,4,83,0,41,2,122,141, - 84,114,121,32,116,111,32,102,105,110,100,32,97,32,115,112, - 101,99,32,102,111,114,32,39,102,117,108,108,110,97,109,101, - 39,32,111,110,32,115,121,115,46,112,97,116,104,32,111,114, - 32,39,112,97,116,104,39,46,10,10,32,32,32,32,32,32, - 32,32,84,104,101,32,115,101,97,114,99,104,32,105,115,32, - 98,97,115,101,100,32,111,110,32,115,121,115,46,112,97,116, - 104,95,104,111,111,107,115,32,97,110,100,32,115,121,115,46, - 112,97,116,104,95,105,109,112,111,114,116,101,114,95,99,97, - 99,104,101,46,10,32,32,32,32,32,32,32,32,78,41,7, - 114,15,0,0,0,114,65,0,0,0,114,93,1,0,0,114, - 164,0,0,0,114,202,0,0,0,114,205,0,0,0,114,47, - 1,0,0,41,6,114,221,0,0,0,114,163,0,0,0,114, - 65,0,0,0,114,225,0,0,0,114,210,0,0,0,114,92, - 1,0,0,114,7,0,0,0,114,7,0,0,0,114,8,0, - 0,0,114,226,0,0,0,151,5,0,0,115,26,0,0,0, - 8,6,6,1,14,1,8,1,4,1,10,1,6,1,4,1, - 6,3,16,1,4,1,4,2,4,2,122,20,80,97,116,104, - 70,105,110,100,101,114,46,102,105,110,100,95,115,112,101,99, - 99,3,0,0,0,0,0,0,0,0,0,0,0,4,0,0, - 0,4,0,0,0,67,0,0,0,115,42,0,0,0,116,0, - 160,1,100,1,116,2,161,2,1,0,124,0,160,3,124,1, - 124,2,161,2,125,3,124,3,100,2,117,0,114,18,100,2, - 83,0,124,3,106,4,83,0,41,3,122,170,102,105,110,100, - 32,116,104,101,32,109,111,100,117,108,101,32,111,110,32,115, - 121,115,46,112,97,116,104,32,111,114,32,39,112,97,116,104, - 39,32,98,97,115,101,100,32,111,110,32,115,121,115,46,112, - 97,116,104,95,104,111,111,107,115,32,97,110,100,10,32,32, - 32,32,32,32,32,32,115,121,115,46,112,97,116,104,95,105, - 109,112,111,114,116,101,114,95,99,97,99,104,101,46,10,10, - 32,32,32,32,32,32,32,32,84,104,105,115,32,109,101,116, - 104,111,100,32,105,115,32,100,101,112,114,101,99,97,116,101, - 100,46,32,32,85,115,101,32,102,105,110,100,95,115,112,101, - 99,40,41,32,105,110,115,116,101,97,100,46,10,10,32,32, - 32,32,32,32,32,32,122,101,80,97,116,104,70,105,110,100, - 101,114,46,102,105,110,100,95,109,111,100,117,108,101,40,41, - 32,105,115,32,100,101,112,114,101,99,97,116,101,100,32,97, - 110,100,32,115,108,97,116,101,100,32,102,111,114,32,114,101, - 109,111,118,97,108,32,105,110,32,80,121,116,104,111,110,32, - 51,46,49,50,59,32,117,115,101,32,102,105,110,100,95,115, - 112,101,99,40,41,32,105,110,115,116,101,97,100,78,114,227, - 0,0,0,114,228,0,0,0,114,7,0,0,0,114,7,0, - 0,0,114,8,0,0,0,114,229,0,0,0,175,5,0,0, - 115,14,0,0,0,6,8,2,2,4,254,12,3,8,1,4, - 1,6,1,122,22,80,97,116,104,70,105,110,100,101,114,46, - 102,105,110,100,95,109,111,100,117,108,101,99,0,0,0,0, - 0,0,0,0,0,0,0,0,3,0,0,0,4,0,0,0, - 79,0,0,0,115,28,0,0,0,100,1,100,2,108,0,109, - 1,125,2,1,0,124,2,106,2,124,0,105,0,124,1,164, - 1,142,1,83,0,41,3,97,32,1,0,0,10,32,32,32, - 32,32,32,32,32,70,105,110,100,32,100,105,115,116,114,105, - 98,117,116,105,111,110,115,46,10,10,32,32,32,32,32,32, - 32,32,82,101,116,117,114,110,32,97,110,32,105,116,101,114, - 97,98,108,101,32,111,102,32,97,108,108,32,68,105,115,116, - 114,105,98,117,116,105,111,110,32,105,110,115,116,97,110,99, - 101,115,32,99,97,112,97,98,108,101,32,111,102,10,32,32, - 32,32,32,32,32,32,108,111,97,100,105,110,103,32,116,104, - 101,32,109,101,116,97,100,97,116,97,32,102,111,114,32,112, - 97,99,107,97,103,101,115,32,109,97,116,99,104,105,110,103, - 32,96,96,99,111,110,116,101,120,116,46,110,97,109,101,96, - 96,10,32,32,32,32,32,32,32,32,40,111,114,32,97,108, - 108,32,110,97,109,101,115,32,105,102,32,96,96,78,111,110, - 101,96,96,32,105,110,100,105,99,97,116,101,100,41,32,97, - 108,111,110,103,32,116,104,101,32,112,97,116,104,115,32,105, - 110,32,116,104,101,32,108,105,115,116,10,32,32,32,32,32, - 32,32,32,111,102,32,100,105,114,101,99,116,111,114,105,101, - 115,32,96,96,99,111,110,116,101,120,116,46,112,97,116,104, - 96,96,46,10,32,32,32,32,32,32,32,32,114,0,0,0, - 0,41,1,218,18,77,101,116,97,100,97,116,97,80,97,116, - 104,70,105,110,100,101,114,41,3,90,18,105,109,112,111,114, - 116,108,105,98,46,109,101,116,97,100,97,116,97,114,94,1, - 0,0,218,18,102,105,110,100,95,100,105,115,116,114,105,98, - 117,116,105,111,110,115,41,3,114,144,0,0,0,114,145,0, - 0,0,114,94,1,0,0,114,7,0,0,0,114,7,0,0, - 0,114,8,0,0,0,114,95,1,0,0,191,5,0,0,115, - 4,0,0,0,12,10,16,1,122,29,80,97,116,104,70,105, - 110,100,101,114,46,102,105,110,100,95,100,105,115,116,114,105, - 98,117,116,105,111,110,115,114,69,0,0,0,114,230,0,0, - 0,41,14,114,150,0,0,0,114,149,0,0,0,114,151,0, - 0,0,114,152,0,0,0,114,233,0,0,0,114,80,1,0, - 0,114,86,1,0,0,114,234,0,0,0,114,89,1,0,0, - 114,90,1,0,0,114,93,1,0,0,114,226,0,0,0,114, - 229,0,0,0,114,95,1,0,0,114,7,0,0,0,114,7, - 0,0,0,114,7,0,0,0,114,8,0,0,0,114,79,1, - 0,0,46,5,0,0,115,36,0,0,0,8,0,4,2,2, - 2,10,1,2,12,10,1,2,12,10,1,2,21,10,1,2, - 20,12,1,2,31,12,1,2,23,12,1,2,15,14,1,114, - 79,1,0,0,99,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,3,0,0,0,64,0,0,0,115,90,0, - 0,0,101,0,90,1,100,0,90,2,100,1,90,3,100,2, - 100,3,132,0,90,4,100,4,100,5,132,0,90,5,101,6, - 90,7,100,6,100,7,132,0,90,8,100,8,100,9,132,0, - 90,9,100,19,100,11,100,12,132,1,90,10,100,13,100,14, - 132,0,90,11,101,12,100,15,100,16,132,0,131,1,90,13, - 100,17,100,18,132,0,90,14,100,10,83,0,41,20,218,10, - 70,105,108,101,70,105,110,100,101,114,122,172,70,105,108,101, - 45,98,97,115,101,100,32,102,105,110,100,101,114,46,10,10, - 32,32,32,32,73,110,116,101,114,97,99,116,105,111,110,115, - 32,119,105,116,104,32,116,104,101,32,102,105,108,101,32,115, - 121,115,116,101,109,32,97,114,101,32,99,97,99,104,101,100, - 32,102,111,114,32,112,101,114,102,111,114,109,97,110,99,101, - 44,32,98,101,105,110,103,10,32,32,32,32,114,101,102,114, - 101,115,104,101,100,32,119,104,101,110,32,116,104,101,32,100, - 105,114,101,99,116,111,114,121,32,116,104,101,32,102,105,110, - 100,101,114,32,105,115,32,104,97,110,100,108,105,110,103,32, - 104,97,115,32,98,101,101,110,32,109,111,100,105,102,105,101, - 100,46,10,10,32,32,32,32,99,2,0,0,0,0,0,0, - 0,0,0,0,0,5,0,0,0,6,0,0,0,7,0,0, - 0,115,112,0,0,0,103,0,125,3,124,2,68,0,93,16, - 92,2,137,0,125,4,124,3,160,0,135,0,102,1,100,1, - 100,2,132,8,124,4,68,0,131,1,161,1,1,0,113,4, - 124,3,124,0,95,1,124,1,112,27,100,3,124,0,95,2, - 116,3,124,0,106,2,131,1,115,43,116,4,116,5,160,6, - 161,0,124,0,106,2,131,2,124,0,95,2,100,4,124,0, - 95,7,116,8,131,0,124,0,95,9,116,8,131,0,124,0, - 95,10,100,5,83,0,41,6,122,154,73,110,105,116,105,97, - 108,105,122,101,32,119,105,116,104,32,116,104,101,32,112,97, - 116,104,32,116,111,32,115,101,97,114,99,104,32,111,110,32, - 97,110,100,32,97,32,118,97,114,105,97,98,108,101,32,110, - 117,109,98,101,114,32,111,102,10,32,32,32,32,32,32,32, - 32,50,45,116,117,112,108,101,115,32,99,111,110,116,97,105, - 110,105,110,103,32,116,104,101,32,108,111,97,100,101,114,32, - 97,110,100,32,116,104,101,32,102,105,108,101,32,115,117,102, - 102,105,120,101,115,32,116,104,101,32,108,111,97,100,101,114, - 10,32,32,32,32,32,32,32,32,114,101,99,111,103,110,105, - 122,101,115,46,99,1,0,0,0,0,0,0,0,0,0,0, - 0,2,0,0,0,3,0,0,0,51,0,0,0,115,24,0, - 0,0,129,0,124,0,93,7,125,1,124,1,136,0,102,2, - 86,0,1,0,113,2,100,0,83,0,114,69,0,0,0,114, - 7,0,0,0,114,43,1,0,0,169,1,114,164,0,0,0, - 114,7,0,0,0,114,8,0,0,0,114,9,0,0,0,220, - 5,0,0,115,4,0,0,0,2,128,22,0,122,38,70,105, - 108,101,70,105,110,100,101,114,46,95,95,105,110,105,116,95, - 95,46,60,108,111,99,97,108,115,62,46,60,103,101,110,101, - 120,112,114,62,114,97,0,0,0,114,130,0,0,0,78,41, - 11,114,191,0,0,0,218,8,95,108,111,97,100,101,114,115, - 114,65,0,0,0,114,86,0,0,0,114,67,0,0,0,114, - 18,0,0,0,114,82,0,0,0,218,11,95,112,97,116,104, - 95,109,116,105,109,101,218,3,115,101,116,218,11,95,112,97, - 116,104,95,99,97,99,104,101,218,19,95,114,101,108,97,120, - 101,100,95,112,97,116,104,95,99,97,99,104,101,41,5,114, - 143,0,0,0,114,65,0,0,0,218,14,108,111,97,100,101, - 114,95,100,101,116,97,105,108,115,90,7,108,111,97,100,101, - 114,115,114,212,0,0,0,114,7,0,0,0,114,97,1,0, - 0,114,8,0,0,0,114,236,0,0,0,214,5,0,0,115, - 20,0,0,0,4,4,12,1,26,1,6,1,10,2,10,1, - 18,1,6,1,8,1,12,1,122,19,70,105,108,101,70,105, - 110,100,101,114,46,95,95,105,110,105,116,95,95,99,1,0, - 0,0,0,0,0,0,0,0,0,0,1,0,0,0,2,0, - 0,0,67,0,0,0,115,10,0,0,0,100,1,124,0,95, - 0,100,2,83,0,41,3,122,31,73,110,118,97,108,105,100, - 97,116,101,32,116,104,101,32,100,105,114,101,99,116,111,114, - 121,32,109,116,105,109,101,46,114,130,0,0,0,78,41,1, - 114,99,1,0,0,114,21,1,0,0,114,7,0,0,0,114, - 7,0,0,0,114,8,0,0,0,114,80,1,0,0,230,5, - 0,0,114,81,0,0,0,122,28,70,105,108,101,70,105,110, - 100,101,114,46,105,110,118,97,108,105,100,97,116,101,95,99, - 97,99,104,101,115,99,2,0,0,0,0,0,0,0,0,0, - 0,0,3,0,0,0,4,0,0,0,67,0,0,0,115,54, - 0,0,0,116,0,160,1,100,1,116,2,161,2,1,0,124, - 0,160,3,124,1,161,1,125,2,124,2,100,2,117,0,114, - 19,100,2,103,0,102,2,83,0,124,2,106,4,124,2,106, - 5,112,25,103,0,102,2,83,0,41,3,122,197,84,114,121, - 32,116,111,32,102,105,110,100,32,97,32,108,111,97,100,101, - 114,32,102,111,114,32,116,104,101,32,115,112,101,99,105,102, - 105,101,100,32,109,111,100,117,108,101,44,32,111,114,32,116, - 104,101,32,110,97,109,101,115,112,97,99,101,10,32,32,32, - 32,32,32,32,32,112,97,99,107,97,103,101,32,112,111,114, - 116,105,111,110,115,46,32,82,101,116,117,114,110,115,32,40, - 108,111,97,100,101,114,44,32,108,105,115,116,45,111,102,45, - 112,111,114,116,105,111,110,115,41,46,10,10,32,32,32,32, - 32,32,32,32,84,104,105,115,32,109,101,116,104,111,100,32, - 105,115,32,100,101,112,114,101,99,97,116,101,100,46,32,32, - 85,115,101,32,102,105,110,100,95,115,112,101,99,40,41,32, - 105,110,115,116,101,97,100,46,10,10,32,32,32,32,32,32, - 32,32,122,101,70,105,108,101,70,105,110,100,101,114,46,102, - 105,110,100,95,108,111,97,100,101,114,40,41,32,105,115,32, - 100,101,112,114,101,99,97,116,101,100,32,97,110,100,32,115, - 108,97,116,101,100,32,102,111,114,32,114,101,109,111,118,97, - 108,32,105,110,32,80,121,116,104,111,110,32,51,46,49,50, - 59,32,117,115,101,32,102,105,110,100,95,115,112,101,99,40, - 41,32,105,110,115,116,101,97,100,78,41,6,114,99,0,0, - 0,114,100,0,0,0,114,101,0,0,0,114,226,0,0,0, - 114,164,0,0,0,114,202,0,0,0,41,3,114,143,0,0, - 0,114,163,0,0,0,114,210,0,0,0,114,7,0,0,0, - 114,7,0,0,0,114,8,0,0,0,114,161,0,0,0,236, - 5,0,0,115,14,0,0,0,6,7,2,2,4,254,10,3, - 8,1,8,1,16,1,122,22,70,105,108,101,70,105,110,100, - 101,114,46,102,105,110,100,95,108,111,97,100,101,114,99,6, - 0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,6, - 0,0,0,67,0,0,0,115,26,0,0,0,124,1,124,2, - 124,3,131,2,125,6,116,0,124,2,124,3,124,6,124,4, - 100,1,141,4,83,0,41,2,78,114,201,0,0,0,41,1, - 114,213,0,0,0,41,7,114,143,0,0,0,114,211,0,0, - 0,114,163,0,0,0,114,65,0,0,0,90,4,115,109,115, - 108,114,225,0,0,0,114,164,0,0,0,114,7,0,0,0, - 114,7,0,0,0,114,8,0,0,0,114,93,1,0,0,251, - 5,0,0,115,8,0,0,0,10,1,8,1,2,1,6,255, - 122,20,70,105,108,101,70,105,110,100,101,114,46,95,103,101, - 116,95,115,112,101,99,78,99,3,0,0,0,0,0,0,0, - 0,0,0,0,14,0,0,0,9,0,0,0,67,0,0,0, - 115,122,1,0,0,100,1,125,3,124,1,160,0,100,2,161, - 1,100,3,25,0,125,4,122,12,116,1,124,0,106,2,112, - 17,116,3,160,4,161,0,131,1,106,5,125,5,87,0,110, - 11,4,0,116,6,121,32,1,0,1,0,1,0,100,4,125, - 5,89,0,110,1,119,0,124,5,124,0,106,7,107,3,114, - 45,124,0,160,8,161,0,1,0,124,5,124,0,95,7,116, - 9,131,0,114,56,124,0,106,10,125,6,124,4,160,11,161, - 0,125,7,110,5,124,0,106,12,125,6,124,4,125,7,124, - 7,124,6,118,0,114,108,116,13,124,0,106,2,124,4,131, - 2,125,8,124,0,106,14,68,0,93,29,92,2,125,9,125, - 10,100,5,124,9,23,0,125,11,116,13,124,8,124,11,131, - 2,125,12,116,15,124,12,131,1,114,103,124,0,160,16,124, - 10,124,1,124,12,124,8,103,1,124,2,161,5,2,0,1, - 0,83,0,113,74,116,17,124,8,131,1,125,3,124,0,106, - 14,68,0,93,55,92,2,125,9,125,10,122,10,116,13,124, - 0,106,2,124,4,124,9,23,0,131,2,125,12,87,0,110, - 11,4,0,116,18,121,136,1,0,1,0,1,0,89,0,1, - 0,100,6,83,0,119,0,116,19,106,20,100,7,124,12,100, - 3,100,8,141,3,1,0,124,7,124,9,23,0,124,6,118, - 0,114,166,116,15,124,12,131,1,114,166,124,0,160,16,124, - 10,124,1,124,12,100,6,124,2,161,5,2,0,1,0,83, - 0,113,111,124,3,114,187,116,19,160,20,100,9,124,8,161, - 2,1,0,116,19,160,21,124,1,100,6,161,2,125,13,124, - 8,103,1,124,13,95,22,124,13,83,0,100,6,83,0,41, - 10,122,111,84,114,121,32,116,111,32,102,105,110,100,32,97, - 32,115,112,101,99,32,102,111,114,32,116,104,101,32,115,112, - 101,99,105,102,105,101,100,32,109,111,100,117,108,101,46,10, - 10,32,32,32,32,32,32,32,32,82,101,116,117,114,110,115, - 32,116,104,101,32,109,97,116,99,104,105,110,103,32,115,112, - 101,99,44,32,111,114,32,78,111,110,101,32,105,102,32,110, - 111,116,32,102,111,117,110,100,46,10,32,32,32,32,32,32, - 32,32,70,114,97,0,0,0,114,44,0,0,0,114,130,0, - 0,0,114,236,0,0,0,78,122,9,116,114,121,105,110,103, - 32,123,125,41,1,90,9,118,101,114,98,111,115,105,116,121, - 122,25,112,111,115,115,105,98,108,101,32,110,97,109,101,115, - 112,97,99,101,32,102,111,114,32,123,125,41,23,114,104,0, - 0,0,114,75,0,0,0,114,65,0,0,0,114,18,0,0, - 0,114,82,0,0,0,114,35,1,0,0,114,76,0,0,0, - 114,99,1,0,0,218,11,95,102,105,108,108,95,99,97,99, - 104,101,114,21,0,0,0,114,102,1,0,0,114,131,0,0, - 0,114,101,1,0,0,114,67,0,0,0,114,98,1,0,0, - 114,80,0,0,0,114,93,1,0,0,114,83,0,0,0,114, - 111,0,0,0,114,159,0,0,0,114,173,0,0,0,114,207, - 0,0,0,114,202,0,0,0,41,14,114,143,0,0,0,114, - 163,0,0,0,114,225,0,0,0,90,12,105,115,95,110,97, - 109,101,115,112,97,99,101,90,11,116,97,105,108,95,109,111, - 100,117,108,101,114,193,0,0,0,90,5,99,97,99,104,101, - 90,12,99,97,99,104,101,95,109,111,100,117,108,101,90,9, - 98,97,115,101,95,112,97,116,104,114,44,1,0,0,114,211, - 0,0,0,90,13,105,110,105,116,95,102,105,108,101,110,97, - 109,101,90,9,102,117,108,108,95,112,97,116,104,114,210,0, - 0,0,114,7,0,0,0,114,7,0,0,0,114,8,0,0, - 0,114,226,0,0,0,0,6,0,0,115,86,0,0,0,4, - 5,14,1,2,1,24,1,12,1,8,1,2,255,10,2,8, - 1,6,1,6,2,6,1,10,1,6,2,4,1,8,2,12, - 1,14,1,8,1,10,1,8,1,24,1,2,255,8,5,14, - 2,2,1,20,1,12,1,8,1,2,255,16,2,12,1,8, - 1,10,1,4,1,8,255,2,128,4,2,12,1,12,1,8, - 1,4,1,4,1,122,20,70,105,108,101,70,105,110,100,101, - 114,46,102,105,110,100,95,115,112,101,99,99,1,0,0,0, - 0,0,0,0,0,0,0,0,9,0,0,0,10,0,0,0, - 67,0,0,0,115,192,0,0,0,124,0,106,0,125,1,122, - 11,116,1,160,2,124,1,112,11,116,1,160,3,161,0,161, - 1,125,2,87,0,110,14,4,0,116,4,116,5,116,6,102, - 3,121,28,1,0,1,0,1,0,103,0,125,2,89,0,110, - 1,119,0,116,7,106,8,160,9,100,1,161,1,115,41,116, - 10,124,2,131,1,124,0,95,11,110,37,116,10,131,0,125, - 3,124,2,68,0,93,28,125,4,124,4,160,12,100,2,161, - 1,92,3,125,5,125,6,125,7,124,6,114,67,100,3,160, - 13,124,5,124,7,160,14,161,0,161,2,125,8,110,2,124, - 5,125,8,124,3,160,15,124,8,161,1,1,0,113,46,124, - 3,124,0,95,11,116,7,106,8,160,9,116,16,161,1,114, - 94,100,4,100,5,132,0,124,2,68,0,131,1,124,0,95, - 17,100,6,83,0,100,6,83,0,41,7,122,68,70,105,108, - 108,32,116,104,101,32,99,97,99,104,101,32,111,102,32,112, - 111,116,101,110,116,105,97,108,32,109,111,100,117,108,101,115, - 32,97,110,100,32,112,97,99,107,97,103,101,115,32,102,111, - 114,32,116,104,105,115,32,100,105,114,101,99,116,111,114,121, - 46,114,14,0,0,0,114,97,0,0,0,114,88,0,0,0, - 99,1,0,0,0,0,0,0,0,0,0,0,0,2,0,0, - 0,4,0,0,0,83,0,0,0,115,20,0,0,0,104,0, - 124,0,93,6,125,1,124,1,160,0,161,0,146,2,113,2, - 83,0,114,7,0,0,0,41,1,114,131,0,0,0,41,2, - 114,5,0,0,0,90,2,102,110,114,7,0,0,0,114,7, - 0,0,0,114,8,0,0,0,114,13,0,0,0,80,6,0, - 0,115,2,0,0,0,20,0,122,41,70,105,108,101,70,105, - 110,100,101,114,46,95,102,105,108,108,95,99,97,99,104,101, - 46,60,108,111,99,97,108,115,62,46,60,115,101,116,99,111, - 109,112,62,78,41,18,114,65,0,0,0,114,18,0,0,0, - 90,7,108,105,115,116,100,105,114,114,82,0,0,0,114,87, - 1,0,0,218,15,80,101,114,109,105,115,115,105,111,110,69, - 114,114,111,114,218,18,78,111,116,65,68,105,114,101,99,116, - 111,114,121,69,114,114,111,114,114,15,0,0,0,114,25,0, - 0,0,114,26,0,0,0,114,100,1,0,0,114,101,1,0, - 0,114,126,0,0,0,114,89,0,0,0,114,131,0,0,0, - 218,3,97,100,100,114,27,0,0,0,114,102,1,0,0,41, - 9,114,143,0,0,0,114,65,0,0,0,90,8,99,111,110, - 116,101,110,116,115,90,21,108,111,119,101,114,95,115,117,102, - 102,105,120,95,99,111,110,116,101,110,116,115,114,72,1,0, - 0,114,141,0,0,0,114,56,1,0,0,114,44,1,0,0, - 90,8,110,101,119,95,110,97,109,101,114,7,0,0,0,114, - 7,0,0,0,114,8,0,0,0,114,104,1,0,0,51,6, - 0,0,115,38,0,0,0,6,2,2,1,22,1,18,1,8, - 3,2,253,12,6,12,1,6,7,8,1,16,1,4,1,18, - 1,4,2,12,1,6,1,12,1,20,1,4,255,122,22,70, - 105,108,101,70,105,110,100,101,114,46,95,102,105,108,108,95, - 99,97,99,104,101,99,1,0,0,0,0,0,0,0,0,0, - 0,0,3,0,0,0,3,0,0,0,7,0,0,0,115,18, - 0,0,0,135,0,135,1,102,2,100,1,100,2,132,8,125, - 2,124,2,83,0,41,3,97,20,1,0,0,65,32,99,108, - 97,115,115,32,109,101,116,104,111,100,32,119,104,105,99,104, - 32,114,101,116,117,114,110,115,32,97,32,99,108,111,115,117, - 114,101,32,116,111,32,117,115,101,32,111,110,32,115,121,115, - 46,112,97,116,104,95,104,111,111,107,10,32,32,32,32,32, - 32,32,32,119,104,105,99,104,32,119,105,108,108,32,114,101, - 116,117,114,110,32,97,110,32,105,110,115,116,97,110,99,101, - 32,117,115,105,110,103,32,116,104,101,32,115,112,101,99,105, - 102,105,101,100,32,108,111,97,100,101,114,115,32,97,110,100, - 32,116,104,101,32,112,97,116,104,10,32,32,32,32,32,32, - 32,32,99,97,108,108,101,100,32,111,110,32,116,104,101,32, - 99,108,111,115,117,114,101,46,10,10,32,32,32,32,32,32, - 32,32,73,102,32,116,104,101,32,112,97,116,104,32,99,97, - 108,108,101,100,32,111,110,32,116,104,101,32,99,108,111,115, - 117,114,101,32,105,115,32,110,111,116,32,97,32,100,105,114, - 101,99,116,111,114,121,44,32,73,109,112,111,114,116,69,114, - 114,111,114,32,105,115,10,32,32,32,32,32,32,32,32,114, - 97,105,115,101,100,46,10,10,32,32,32,32,32,32,32,32, - 99,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0, - 0,4,0,0,0,19,0,0,0,115,36,0,0,0,116,0, - 124,0,131,1,115,10,116,1,100,1,124,0,100,2,141,2, - 130,1,136,0,124,0,103,1,136,1,162,1,82,0,142,0, - 83,0,41,3,122,45,80,97,116,104,32,104,111,111,107,32, - 102,111,114,32,105,109,112,111,114,116,108,105,98,46,109,97, - 99,104,105,110,101,114,121,46,70,105,108,101,70,105,110,100, - 101,114,46,122,30,111,110,108,121,32,100,105,114,101,99,116, - 111,114,105,101,115,32,97,114,101,32,115,117,112,112,111,114, - 116,101,100,114,71,0,0,0,41,2,114,83,0,0,0,114, - 142,0,0,0,114,71,0,0,0,169,2,114,221,0,0,0, - 114,103,1,0,0,114,7,0,0,0,114,8,0,0,0,218, - 24,112,97,116,104,95,104,111,111,107,95,102,111,114,95,70, - 105,108,101,70,105,110,100,101,114,92,6,0,0,115,6,0, - 0,0,8,2,12,1,16,1,122,54,70,105,108,101,70,105, - 110,100,101,114,46,112,97,116,104,95,104,111,111,107,46,60, - 108,111,99,97,108,115,62,46,112,97,116,104,95,104,111,111, - 107,95,102,111,114,95,70,105,108,101,70,105,110,100,101,114, - 114,7,0,0,0,41,3,114,221,0,0,0,114,103,1,0, - 0,114,109,1,0,0,114,7,0,0,0,114,108,1,0,0, - 114,8,0,0,0,218,9,112,97,116,104,95,104,111,111,107, - 82,6,0,0,115,4,0,0,0,14,10,4,6,122,20,70, - 105,108,101,70,105,110,100,101,114,46,112,97,116,104,95,104, - 111,111,107,99,1,0,0,0,0,0,0,0,0,0,0,0, - 1,0,0,0,3,0,0,0,67,0,0,0,114,69,1,0, - 0,41,2,78,122,16,70,105,108,101,70,105,110,100,101,114, - 40,123,33,114,125,41,41,2,114,89,0,0,0,114,65,0, - 0,0,114,21,1,0,0,114,7,0,0,0,114,7,0,0, - 0,114,8,0,0,0,114,70,1,0,0,100,6,0,0,114, - 63,1,0,0,122,19,70,105,108,101,70,105,110,100,101,114, - 46,95,95,114,101,112,114,95,95,114,69,0,0,0,41,15, - 114,150,0,0,0,114,149,0,0,0,114,151,0,0,0,114, - 152,0,0,0,114,236,0,0,0,114,80,1,0,0,114,167, - 0,0,0,114,229,0,0,0,114,161,0,0,0,114,93,1, - 0,0,114,226,0,0,0,114,104,1,0,0,114,234,0,0, - 0,114,110,1,0,0,114,70,1,0,0,114,7,0,0,0, - 114,7,0,0,0,114,7,0,0,0,114,8,0,0,0,114, - 96,1,0,0,205,5,0,0,115,24,0,0,0,8,0,4, - 2,8,7,8,16,4,4,8,2,8,15,10,5,8,51,2, - 31,10,1,12,17,114,96,1,0,0,99,4,0,0,0,0, - 0,0,0,0,0,0,0,6,0,0,0,8,0,0,0,67, - 0,0,0,115,144,0,0,0,124,0,160,0,100,1,161,1, - 125,4,124,0,160,0,100,2,161,1,125,5,124,4,115,33, - 124,5,114,18,124,5,106,1,125,4,110,15,124,2,124,3, - 107,2,114,28,116,2,124,1,124,2,131,2,125,4,110,5, - 116,3,124,1,124,2,131,2,125,4,124,5,115,42,116,4, - 124,1,124,2,124,4,100,3,141,3,125,5,122,19,124,5, - 124,0,100,2,60,0,124,4,124,0,100,1,60,0,124,2, - 124,0,100,4,60,0,124,3,124,0,100,5,60,0,87,0, - 100,0,83,0,4,0,116,5,121,71,1,0,1,0,1,0, - 89,0,100,0,83,0,119,0,41,6,78,218,10,95,95,108, - 111,97,100,101,114,95,95,218,8,95,95,115,112,101,99,95, - 95,114,97,1,0,0,90,8,95,95,102,105,108,101,95,95, - 90,10,95,95,99,97,99,104,101,100,95,95,41,6,218,3, - 103,101,116,114,164,0,0,0,114,41,1,0,0,114,34,1, - 0,0,114,213,0,0,0,218,9,69,120,99,101,112,116,105, - 111,110,41,6,90,2,110,115,114,141,0,0,0,90,8,112, - 97,116,104,110,97,109,101,90,9,99,112,97,116,104,110,97, - 109,101,114,164,0,0,0,114,210,0,0,0,114,7,0,0, - 0,114,7,0,0,0,114,8,0,0,0,218,14,95,102,105, - 120,95,117,112,95,109,111,100,117,108,101,106,6,0,0,115, - 36,0,0,0,10,2,10,1,4,1,4,1,8,1,8,1, - 12,1,10,2,4,1,14,1,2,1,8,1,8,1,8,1, - 14,1,12,1,6,2,2,254,114,115,1,0,0,99,0,0, - 0,0,0,0,0,0,0,0,0,0,3,0,0,0,3,0, - 0,0,67,0,0,0,115,38,0,0,0,116,0,116,1,160, - 2,161,0,102,2,125,0,116,3,116,4,102,2,125,1,116, - 5,116,6,102,2,125,2,124,0,124,1,124,2,103,3,83, - 0,41,1,122,95,82,101,116,117,114,110,115,32,97,32,108, - 105,115,116,32,111,102,32,102,105,108,101,45,98,97,115,101, - 100,32,109,111,100,117,108,101,32,108,111,97,100,101,114,115, - 46,10,10,32,32,32,32,69,97,99,104,32,105,116,101,109, - 32,105,115,32,97,32,116,117,112,108,101,32,40,108,111,97, - 100,101,114,44,32,115,117,102,102,105,120,101,115,41,46,10, - 32,32,32,32,41,7,114,30,1,0,0,114,187,0,0,0, - 218,18,101,120,116,101,110,115,105,111,110,95,115,117,102,102, - 105,120,101,115,114,34,1,0,0,114,127,0,0,0,114,41, - 1,0,0,114,113,0,0,0,41,3,90,10,101,120,116,101, - 110,115,105,111,110,115,90,6,115,111,117,114,99,101,90,8, - 98,121,116,101,99,111,100,101,114,7,0,0,0,114,7,0, - 0,0,114,8,0,0,0,114,208,0,0,0,129,6,0,0, - 115,8,0,0,0,12,5,8,1,8,1,10,1,114,208,0, - 0,0,99,1,0,0,0,0,0,0,0,0,0,0,0,1, - 0,0,0,1,0,0,0,67,0,0,0,115,8,0,0,0, - 124,0,97,0,100,0,83,0,114,69,0,0,0,41,1,114, - 159,0,0,0,41,1,218,17,95,98,111,111,116,115,116,114, - 97,112,95,109,111,100,117,108,101,114,7,0,0,0,114,7, - 0,0,0,114,8,0,0,0,218,21,95,115,101,116,95,98, - 111,111,116,115,116,114,97,112,95,109,111,100,117,108,101,140, - 6,0,0,115,2,0,0,0,8,2,114,118,1,0,0,99, - 1,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0, - 4,0,0,0,67,0,0,0,115,50,0,0,0,116,0,124, - 0,131,1,1,0,116,1,131,0,125,1,116,2,106,3,160, - 4,116,5,106,6,124,1,142,0,103,1,161,1,1,0,116, - 2,106,7,160,8,116,9,161,1,1,0,100,1,83,0,41, - 2,122,41,73,110,115,116,97,108,108,32,116,104,101,32,112, - 97,116,104,45,98,97,115,101,100,32,105,109,112,111,114,116, - 32,99,111,109,112,111,110,101,110,116,115,46,78,41,10,114, - 118,1,0,0,114,208,0,0,0,114,15,0,0,0,114,85, - 1,0,0,114,191,0,0,0,114,96,1,0,0,114,110,1, - 0,0,218,9,109,101,116,97,95,112,97,116,104,114,61,0, - 0,0,114,79,1,0,0,41,2,114,117,1,0,0,90,17, - 115,117,112,112,111,114,116,101,100,95,108,111,97,100,101,114, - 115,114,7,0,0,0,114,7,0,0,0,114,8,0,0,0, - 218,8,95,105,110,115,116,97,108,108,145,6,0,0,115,8, - 0,0,0,8,2,6,1,20,1,16,1,114,120,1,0,0, - 41,1,114,87,0,0,0,114,69,0,0,0,41,3,78,78, - 78,41,2,114,0,0,0,0,114,0,0,0,0,41,1,84, - 41,85,114,152,0,0,0,114,159,0,0,0,114,187,0,0, - 0,114,91,0,0,0,114,15,0,0,0,114,99,0,0,0, - 114,184,0,0,0,114,25,0,0,0,114,231,0,0,0,90, - 2,110,116,114,18,0,0,0,114,215,0,0,0,90,5,112, - 111,115,105,120,114,50,0,0,0,218,3,97,108,108,114,59, - 0,0,0,114,136,0,0,0,114,57,0,0,0,114,62,0, - 0,0,90,20,95,112,97,116,104,115,101,112,115,95,119,105, - 116,104,95,99,111,108,111,110,114,28,0,0,0,90,37,95, - 67,65,83,69,95,73,78,83,69,78,83,73,84,73,86,69, - 95,80,76,65,84,70,79,82,77,83,95,66,89,84,69,83, - 95,75,69,89,114,27,0,0,0,114,29,0,0,0,114,21, - 0,0,0,114,36,0,0,0,114,42,0,0,0,114,45,0, - 0,0,114,67,0,0,0,114,74,0,0,0,114,75,0,0, - 0,114,79,0,0,0,114,80,0,0,0,114,83,0,0,0, - 114,86,0,0,0,114,95,0,0,0,218,4,116,121,112,101, - 218,8,95,95,99,111,100,101,95,95,114,186,0,0,0,114, - 34,0,0,0,114,172,0,0,0,114,33,0,0,0,114,39, - 0,0,0,114,8,1,0,0,114,116,0,0,0,114,112,0, - 0,0,114,127,0,0,0,114,61,0,0,0,114,116,1,0, - 0,114,232,0,0,0,114,113,0,0,0,90,23,68,69,66, - 85,71,95,66,89,84,69,67,79,68,69,95,83,85,70,70, - 73,88,69,83,90,27,79,80,84,73,77,73,90,69,68,95, - 66,89,84,69,67,79,68,69,95,83,85,70,70,73,88,69, - 83,114,121,0,0,0,114,128,0,0,0,114,135,0,0,0, - 114,137,0,0,0,114,139,0,0,0,114,160,0,0,0,114, - 167,0,0,0,114,176,0,0,0,114,180,0,0,0,114,182, - 0,0,0,114,189,0,0,0,114,194,0,0,0,114,195,0, - 0,0,114,200,0,0,0,218,6,111,98,106,101,99,116,114, - 209,0,0,0,114,213,0,0,0,114,214,0,0,0,114,235, - 0,0,0,114,249,0,0,0,114,11,1,0,0,114,34,1, - 0,0,114,41,1,0,0,114,30,1,0,0,114,47,1,0, - 0,114,75,1,0,0,114,79,1,0,0,114,96,1,0,0, - 114,115,1,0,0,114,208,0,0,0,114,118,1,0,0,114, - 120,1,0,0,114,7,0,0,0,114,7,0,0,0,114,7, - 0,0,0,114,8,0,0,0,218,8,60,109,111,100,117,108, - 101,62,1,0,0,0,115,180,0,0,0,4,0,4,22,8, - 3,8,1,8,1,8,1,8,1,10,3,4,1,8,1,10, - 1,8,2,4,3,10,1,6,2,22,2,8,1,8,1,10, - 1,14,1,4,4,4,1,2,1,2,1,4,255,8,4,6, - 16,8,3,8,5,8,5,4,6,10,1,8,30,8,6,8, - 8,8,10,8,9,8,5,4,7,10,1,8,8,10,5,10, - 22,0,127,16,30,12,1,4,2,4,1,6,2,4,1,10, - 1,8,2,6,2,8,2,16,2,8,71,8,40,8,19,8, - 12,8,12,8,31,8,20,8,33,8,28,10,24,10,13,10, - 10,8,11,6,14,4,3,2,1,12,255,14,73,14,67,16, - 30,0,127,14,17,18,50,18,45,18,25,14,53,14,69,14, - 49,0,127,14,32,0,127,10,30,8,23,8,11,12,5, -}; diff --git a/contrib/tools/python3/src/Python/importlib_zipimport.h b/contrib/tools/python3/src/Python/importlib_zipimport.h deleted file mode 100644 index 3c476841a8c..00000000000 --- a/contrib/tools/python3/src/Python/importlib_zipimport.h +++ /dev/null @@ -1,1063 +0,0 @@ -/* Auto-generated by Programs/_freeze_importlib.c */ -const unsigned char _Py_M__zipimport[] = { - 99,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,4,0,0,0,64,0,0,0,115,80,1,0,0,100,0, - 90,0,100,1,100,2,108,1,90,2,100,1,100,3,108,1, - 109,3,90,3,109,4,90,4,1,0,100,1,100,2,108,5, - 90,6,100,1,100,2,108,7,90,7,100,1,100,2,108,8, - 90,8,100,1,100,2,108,9,90,9,100,1,100,2,108,10, - 90,10,100,1,100,2,108,11,90,11,100,1,100,2,108,12, - 90,12,100,4,100,5,103,2,90,13,101,2,106,14,90,14, - 101,2,106,15,100,6,100,2,133,2,25,0,90,16,71,0, - 100,7,100,4,132,0,100,4,101,17,131,3,90,18,105,0, - 90,19,101,20,101,10,131,1,90,21,100,8,90,22,100,9, - 90,23,100,10,90,24,71,0,100,11,100,5,132,0,100,5, - 101,2,106,25,131,3,90,26,101,14,100,12,23,0,100,13, - 100,13,102,3,101,14,100,14,23,0,100,15,100,13,102,3, - 100,16,100,17,102,4,90,27,100,18,100,19,132,0,90,28, - 100,20,100,21,132,0,90,29,100,22,100,23,132,0,90,30, - 100,24,100,25,132,0,90,31,100,26,90,32,100,15,97,33, - 100,27,100,28,132,0,90,34,100,29,100,30,132,0,90,35, - 100,31,100,32,132,0,90,36,100,33,100,34,132,0,90,37, - 101,20,101,37,106,38,131,1,90,39,100,35,100,36,132,0, - 90,40,100,37,100,38,132,0,90,41,100,39,100,40,132,0, - 90,42,100,41,100,42,132,0,90,43,100,43,100,44,132,0, - 90,44,100,45,100,46,132,0,90,45,100,2,83,0,41,47, - 97,80,2,0,0,122,105,112,105,109,112,111,114,116,32,112, - 114,111,118,105,100,101,115,32,115,117,112,112,111,114,116,32, - 102,111,114,32,105,109,112,111,114,116,105,110,103,32,80,121, - 116,104,111,110,32,109,111,100,117,108,101,115,32,102,114,111, - 109,32,90,105,112,32,97,114,99,104,105,118,101,115,46,10, - 10,84,104,105,115,32,109,111,100,117,108,101,32,101,120,112, - 111,114,116,115,32,116,104,114,101,101,32,111,98,106,101,99, - 116,115,58,10,45,32,122,105,112,105,109,112,111,114,116,101, - 114,58,32,97,32,99,108,97,115,115,59,32,105,116,115,32, - 99,111,110,115,116,114,117,99,116,111,114,32,116,97,107,101, - 115,32,97,32,112,97,116,104,32,116,111,32,97,32,90,105, - 112,32,97,114,99,104,105,118,101,46,10,45,32,90,105,112, - 73,109,112,111,114,116,69,114,114,111,114,58,32,101,120,99, - 101,112,116,105,111,110,32,114,97,105,115,101,100,32,98,121, - 32,122,105,112,105,109,112,111,114,116,101,114,32,111,98,106, - 101,99,116,115,46,32,73,116,39,115,32,97,10,32,32,115, - 117,98,99,108,97,115,115,32,111,102,32,73,109,112,111,114, - 116,69,114,114,111,114,44,32,115,111,32,105,116,32,99,97, - 110,32,98,101,32,99,97,117,103,104,116,32,97,115,32,73, - 109,112,111,114,116,69,114,114,111,114,44,32,116,111,111,46, - 10,45,32,95,122,105,112,95,100,105,114,101,99,116,111,114, - 121,95,99,97,99,104,101,58,32,97,32,100,105,99,116,44, - 32,109,97,112,112,105,110,103,32,97,114,99,104,105,118,101, - 32,112,97,116,104,115,32,116,111,32,122,105,112,32,100,105, - 114,101,99,116,111,114,121,10,32,32,105,110,102,111,32,100, - 105,99,116,115,44,32,97,115,32,117,115,101,100,32,105,110, - 32,122,105,112,105,109,112,111,114,116,101,114,46,95,102,105, - 108,101,115,46,10,10,73,116,32,105,115,32,117,115,117,97, - 108,108,121,32,110,111,116,32,110,101,101,100,101,100,32,116, - 111,32,117,115,101,32,116,104,101,32,122,105,112,105,109,112, - 111,114,116,32,109,111,100,117,108,101,32,101,120,112,108,105, - 99,105,116,108,121,59,32,105,116,32,105,115,10,117,115,101, - 100,32,98,121,32,116,104,101,32,98,117,105,108,116,105,110, - 32,105,109,112,111,114,116,32,109,101,99,104,97,110,105,115, - 109,32,102,111,114,32,115,121,115,46,112,97,116,104,32,105, - 116,101,109,115,32,116,104,97,116,32,97,114,101,32,112,97, - 116,104,115,10,116,111,32,90,105,112,32,97,114,99,104,105, - 118,101,115,46,10,233,0,0,0,0,78,41,2,218,14,95, - 117,110,112,97,99,107,95,117,105,110,116,49,54,218,14,95, - 117,110,112,97,99,107,95,117,105,110,116,51,50,218,14,90, - 105,112,73,109,112,111,114,116,69,114,114,111,114,218,11,122, - 105,112,105,109,112,111,114,116,101,114,233,1,0,0,0,99, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 1,0,0,0,64,0,0,0,115,12,0,0,0,101,0,90, - 1,100,0,90,2,100,1,83,0,41,2,114,3,0,0,0, - 78,41,3,218,8,95,95,110,97,109,101,95,95,218,10,95, - 95,109,111,100,117,108,101,95,95,218,12,95,95,113,117,97, - 108,110,97,109,101,95,95,169,0,114,9,0,0,0,114,9, - 0,0,0,250,18,60,102,114,111,122,101,110,32,122,105,112, - 105,109,112,111,114,116,62,114,3,0,0,0,34,0,0,0, - 115,4,0,0,0,8,0,4,1,233,22,0,0,0,115,4, - 0,0,0,80,75,5,6,105,255,255,0,0,99,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0, - 0,64,0,0,0,115,126,0,0,0,101,0,90,1,100,0, - 90,2,100,1,90,3,100,2,100,3,132,0,90,4,100,29, - 100,5,100,6,132,1,90,5,100,29,100,7,100,8,132,1, - 90,6,100,29,100,9,100,10,132,1,90,7,100,11,100,12, - 132,0,90,8,100,13,100,14,132,0,90,9,100,15,100,16, - 132,0,90,10,100,17,100,18,132,0,90,11,100,19,100,20, - 132,0,90,12,100,21,100,22,132,0,90,13,100,23,100,24, - 132,0,90,14,100,25,100,26,132,0,90,15,100,27,100,28, - 132,0,90,16,100,4,83,0,41,30,114,4,0,0,0,97, - 255,1,0,0,122,105,112,105,109,112,111,114,116,101,114,40, - 97,114,99,104,105,118,101,112,97,116,104,41,32,45,62,32, - 122,105,112,105,109,112,111,114,116,101,114,32,111,98,106,101, - 99,116,10,10,32,32,32,32,67,114,101,97,116,101,32,97, - 32,110,101,119,32,122,105,112,105,109,112,111,114,116,101,114, - 32,105,110,115,116,97,110,99,101,46,32,39,97,114,99,104, - 105,118,101,112,97,116,104,39,32,109,117,115,116,32,98,101, - 32,97,32,112,97,116,104,32,116,111,10,32,32,32,32,97, - 32,122,105,112,102,105,108,101,44,32,111,114,32,116,111,32, - 97,32,115,112,101,99,105,102,105,99,32,112,97,116,104,32, - 105,110,115,105,100,101,32,97,32,122,105,112,102,105,108,101, - 46,32,70,111,114,32,101,120,97,109,112,108,101,44,32,105, - 116,32,99,97,110,32,98,101,10,32,32,32,32,39,47,116, - 109,112,47,109,121,105,109,112,111,114,116,46,122,105,112,39, - 44,32,111,114,32,39,47,116,109,112,47,109,121,105,109,112, - 111,114,116,46,122,105,112,47,109,121,100,105,114,101,99,116, - 111,114,121,39,44,32,105,102,32,109,121,100,105,114,101,99, - 116,111,114,121,32,105,115,32,97,10,32,32,32,32,118,97, - 108,105,100,32,100,105,114,101,99,116,111,114,121,32,105,110, - 115,105,100,101,32,116,104,101,32,97,114,99,104,105,118,101, - 46,10,10,32,32,32,32,39,90,105,112,73,109,112,111,114, - 116,69,114,114,111,114,32,105,115,32,114,97,105,115,101,100, - 32,105,102,32,39,97,114,99,104,105,118,101,112,97,116,104, - 39,32,100,111,101,115,110,39,116,32,112,111,105,110,116,32, - 116,111,32,97,32,118,97,108,105,100,32,90,105,112,10,32, - 32,32,32,97,114,99,104,105,118,101,46,10,10,32,32,32, - 32,84,104,101,32,39,97,114,99,104,105,118,101,39,32,97, - 116,116,114,105,98,117,116,101,32,111,102,32,122,105,112,105, - 109,112,111,114,116,101,114,32,111,98,106,101,99,116,115,32, - 99,111,110,116,97,105,110,115,32,116,104,101,32,110,97,109, - 101,32,111,102,32,116,104,101,10,32,32,32,32,122,105,112, - 102,105,108,101,32,116,97,114,103,101,116,101,100,46,10,32, - 32,32,32,99,2,0,0,0,0,0,0,0,0,0,0,0, - 8,0,0,0,9,0,0,0,67,0,0,0,115,36,1,0, - 0,116,0,124,1,116,1,131,2,115,14,100,1,100,0,108, - 2,125,2,124,2,160,3,124,1,161,1,125,1,124,1,115, - 22,116,4,100,2,124,1,100,3,141,2,130,1,116,5,114, - 30,124,1,160,6,116,5,116,7,161,2,125,1,103,0,125, - 3,9,0,122,7,116,8,160,9,124,1,161,1,125,4,87, - 0,110,35,4,0,116,10,116,11,102,2,121,75,1,0,1, - 0,1,0,116,8,160,12,124,1,161,1,92,2,125,5,125, - 6,124,5,124,1,107,2,114,66,116,4,100,5,124,1,100, - 3,141,2,130,1,124,5,125,1,124,3,160,13,124,6,161, - 1,1,0,89,0,110,15,119,0,124,4,106,14,100,6,64, - 0,100,7,107,3,114,89,116,4,100,5,124,1,100,3,141, - 2,130,1,110,1,113,33,122,6,116,15,124,1,25,0,125, - 7,87,0,110,17,4,0,116,16,121,114,1,0,1,0,1, - 0,116,17,124,1,131,1,125,7,124,7,116,15,124,1,60, - 0,89,0,110,1,119,0,124,7,124,0,95,18,124,1,124, - 0,95,19,116,8,106,20,124,3,100,0,100,0,100,8,133, - 3,25,0,142,0,124,0,95,21,124,0,106,21,114,144,124, - 0,4,0,106,21,116,7,55,0,2,0,95,21,100,0,83, - 0,100,0,83,0,41,9,78,114,0,0,0,0,122,21,97, - 114,99,104,105,118,101,32,112,97,116,104,32,105,115,32,101, - 109,112,116,121,169,1,218,4,112,97,116,104,84,122,14,110, - 111,116,32,97,32,90,105,112,32,102,105,108,101,105,0,240, - 0,0,105,0,128,0,0,233,255,255,255,255,41,22,218,10, - 105,115,105,110,115,116,97,110,99,101,218,3,115,116,114,218, - 2,111,115,90,8,102,115,100,101,99,111,100,101,114,3,0, - 0,0,218,12,97,108,116,95,112,97,116,104,95,115,101,112, - 218,7,114,101,112,108,97,99,101,218,8,112,97,116,104,95, - 115,101,112,218,19,95,98,111,111,116,115,116,114,97,112,95, - 101,120,116,101,114,110,97,108,90,10,95,112,97,116,104,95, - 115,116,97,116,218,7,79,83,69,114,114,111,114,218,10,86, - 97,108,117,101,69,114,114,111,114,90,11,95,112,97,116,104, - 95,115,112,108,105,116,218,6,97,112,112,101,110,100,90,7, - 115,116,95,109,111,100,101,218,20,95,122,105,112,95,100,105, - 114,101,99,116,111,114,121,95,99,97,99,104,101,218,8,75, - 101,121,69,114,114,111,114,218,15,95,114,101,97,100,95,100, - 105,114,101,99,116,111,114,121,218,6,95,102,105,108,101,115, - 218,7,97,114,99,104,105,118,101,218,10,95,112,97,116,104, - 95,106,111,105,110,218,6,112,114,101,102,105,120,41,8,218, - 4,115,101,108,102,114,13,0,0,0,114,17,0,0,0,114, - 31,0,0,0,90,2,115,116,90,7,100,105,114,110,97,109, - 101,90,8,98,97,115,101,110,97,109,101,218,5,102,105,108, - 101,115,114,9,0,0,0,114,9,0,0,0,114,10,0,0, - 0,218,8,95,95,105,110,105,116,95,95,64,0,0,0,115, - 68,0,0,0,10,1,8,1,10,1,4,1,12,1,4,1, - 12,1,4,2,2,1,2,1,14,1,16,1,14,3,8,1, - 12,1,4,1,14,1,2,249,14,10,12,2,2,1,2,240, - 2,18,12,1,12,1,8,1,12,1,2,254,6,3,6,1, - 22,2,6,1,18,1,4,255,122,20,122,105,112,105,109,112, - 111,114,116,101,114,46,95,95,105,110,105,116,95,95,78,99, - 3,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0, - 4,0,0,0,67,0,0,0,115,90,0,0,0,116,0,160, - 1,100,1,116,2,161,2,1,0,116,3,124,0,124,1,131, - 2,125,3,124,3,100,2,117,1,114,19,124,0,103,0,102, - 2,83,0,116,4,124,0,124,1,131,2,125,4,116,5,124, - 0,124,4,131,2,114,41,100,2,124,0,106,6,155,0,116, - 7,155,0,124,4,155,0,157,3,103,1,102,2,83,0,100, - 2,103,0,102,2,83,0,41,3,97,47,2,0,0,102,105, - 110,100,95,108,111,97,100,101,114,40,102,117,108,108,110,97, - 109,101,44,32,112,97,116,104,61,78,111,110,101,41,32,45, - 62,32,115,101,108,102,44,32,115,116,114,32,111,114,32,78, - 111,110,101,46,10,10,32,32,32,32,32,32,32,32,83,101, - 97,114,99,104,32,102,111,114,32,97,32,109,111,100,117,108, - 101,32,115,112,101,99,105,102,105,101,100,32,98,121,32,39, - 102,117,108,108,110,97,109,101,39,46,32,39,102,117,108,108, - 110,97,109,101,39,32,109,117,115,116,32,98,101,32,116,104, - 101,10,32,32,32,32,32,32,32,32,102,117,108,108,121,32, - 113,117,97,108,105,102,105,101,100,32,40,100,111,116,116,101, - 100,41,32,109,111,100,117,108,101,32,110,97,109,101,46,32, - 73,116,32,114,101,116,117,114,110,115,32,116,104,101,32,122, - 105,112,105,109,112,111,114,116,101,114,10,32,32,32,32,32, - 32,32,32,105,110,115,116,97,110,99,101,32,105,116,115,101, - 108,102,32,105,102,32,116,104,101,32,109,111,100,117,108,101, - 32,119,97,115,32,102,111,117,110,100,44,32,97,32,115,116, - 114,105,110,103,32,99,111,110,116,97,105,110,105,110,103,32, - 116,104,101,10,32,32,32,32,32,32,32,32,102,117,108,108, - 32,112,97,116,104,32,110,97,109,101,32,105,102,32,105,116, - 39,115,32,112,111,115,115,105,98,108,121,32,97,32,112,111, - 114,116,105,111,110,32,111,102,32,97,32,110,97,109,101,115, - 112,97,99,101,32,112,97,99,107,97,103,101,44,10,32,32, - 32,32,32,32,32,32,111,114,32,78,111,110,101,32,111,116, - 104,101,114,119,105,115,101,46,32,84,104,101,32,111,112,116, - 105,111,110,97,108,32,39,112,97,116,104,39,32,97,114,103, - 117,109,101,110,116,32,105,115,32,105,103,110,111,114,101,100, - 32,45,45,32,105,116,39,115,10,32,32,32,32,32,32,32, - 32,116,104,101,114,101,32,102,111,114,32,99,111,109,112,97, - 116,105,98,105,108,105,116,121,32,119,105,116,104,32,116,104, - 101,32,105,109,112,111,114,116,101,114,32,112,114,111,116,111, - 99,111,108,46,10,10,32,32,32,32,32,32,32,32,68,101, - 112,114,101,99,97,116,101,100,32,115,105,110,99,101,32,80, - 121,116,104,111,110,32,51,46,49,48,46,32,85,115,101,32, - 102,105,110,100,95,115,112,101,99,40,41,32,105,110,115,116, - 101,97,100,46,10,32,32,32,32,32,32,32,32,122,102,122, - 105,112,105,109,112,111,114,116,101,114,46,102,105,110,100,95, - 108,111,97,100,101,114,40,41,32,105,115,32,100,101,112,114, - 101,99,97,116,101,100,32,97,110,100,32,115,108,97,116,101, - 100,32,102,111,114,32,114,101,109,111,118,97,108,32,105,110, - 32,80,121,116,104,111,110,32,51,46,49,50,59,32,117,115, - 101,32,102,105,110,100,95,115,112,101,99,40,41,32,105,110, - 115,116,101,97,100,78,41,8,218,9,95,119,97,114,110,105, - 110,103,115,218,4,119,97,114,110,218,18,68,101,112,114,101, - 99,97,116,105,111,110,87,97,114,110,105,110,103,218,16,95, - 103,101,116,95,109,111,100,117,108,101,95,105,110,102,111,218, - 16,95,103,101,116,95,109,111,100,117,108,101,95,112,97,116, - 104,218,7,95,105,115,95,100,105,114,114,29,0,0,0,114, - 20,0,0,0,41,5,114,32,0,0,0,218,8,102,117,108, - 108,110,97,109,101,114,13,0,0,0,218,2,109,105,218,7, - 109,111,100,112,97,116,104,114,9,0,0,0,114,9,0,0, - 0,114,10,0,0,0,218,11,102,105,110,100,95,108,111,97, - 100,101,114,110,0,0,0,115,20,0,0,0,6,12,2,2, - 4,254,10,3,8,1,8,2,10,7,10,1,24,4,8,2, - 122,23,122,105,112,105,109,112,111,114,116,101,114,46,102,105, - 110,100,95,108,111,97,100,101,114,99,3,0,0,0,0,0, - 0,0,0,0,0,0,3,0,0,0,4,0,0,0,67,0, - 0,0,115,28,0,0,0,116,0,160,1,100,1,116,2,161, - 2,1,0,124,0,160,3,124,1,124,2,161,2,100,2,25, - 0,83,0,41,3,97,203,1,0,0,102,105,110,100,95,109, - 111,100,117,108,101,40,102,117,108,108,110,97,109,101,44,32, - 112,97,116,104,61,78,111,110,101,41,32,45,62,32,115,101, - 108,102,32,111,114,32,78,111,110,101,46,10,10,32,32,32, - 32,32,32,32,32,83,101,97,114,99,104,32,102,111,114,32, - 97,32,109,111,100,117,108,101,32,115,112,101,99,105,102,105, - 101,100,32,98,121,32,39,102,117,108,108,110,97,109,101,39, - 46,32,39,102,117,108,108,110,97,109,101,39,32,109,117,115, - 116,32,98,101,32,116,104,101,10,32,32,32,32,32,32,32, - 32,102,117,108,108,121,32,113,117,97,108,105,102,105,101,100, - 32,40,100,111,116,116,101,100,41,32,109,111,100,117,108,101, - 32,110,97,109,101,46,32,73,116,32,114,101,116,117,114,110, - 115,32,116,104,101,32,122,105,112,105,109,112,111,114,116,101, - 114,10,32,32,32,32,32,32,32,32,105,110,115,116,97,110, - 99,101,32,105,116,115,101,108,102,32,105,102,32,116,104,101, - 32,109,111,100,117,108,101,32,119,97,115,32,102,111,117,110, - 100,44,32,111,114,32,78,111,110,101,32,105,102,32,105,116, - 32,119,97,115,110,39,116,46,10,32,32,32,32,32,32,32, - 32,84,104,101,32,111,112,116,105,111,110,97,108,32,39,112, - 97,116,104,39,32,97,114,103,117,109,101,110,116,32,105,115, - 32,105,103,110,111,114,101,100,32,45,45,32,105,116,39,115, - 32,116,104,101,114,101,32,102,111,114,32,99,111,109,112,97, - 116,105,98,105,108,105,116,121,10,32,32,32,32,32,32,32, - 32,119,105,116,104,32,116,104,101,32,105,109,112,111,114,116, - 101,114,32,112,114,111,116,111,99,111,108,46,10,10,32,32, - 32,32,32,32,32,32,68,101,112,114,101,99,97,116,101,100, - 32,115,105,110,99,101,32,80,121,116,104,111,110,32,51,46, - 49,48,46,32,85,115,101,32,102,105,110,100,95,115,112,101, - 99,40,41,32,105,110,115,116,101,97,100,46,10,32,32,32, - 32,32,32,32,32,122,102,122,105,112,105,109,112,111,114,116, - 101,114,46,102,105,110,100,95,109,111,100,117,108,101,40,41, - 32,105,115,32,100,101,112,114,101,99,97,116,101,100,32,97, - 110,100,32,115,108,97,116,101,100,32,102,111,114,32,114,101, - 109,111,118,97,108,32,105,110,32,80,121,116,104,111,110,32, - 51,46,49,50,59,32,117,115,101,32,102,105,110,100,95,115, - 112,101,99,40,41,32,105,110,115,116,101,97,100,114,0,0, - 0,0,41,4,114,35,0,0,0,114,36,0,0,0,114,37, - 0,0,0,114,44,0,0,0,41,3,114,32,0,0,0,114, - 41,0,0,0,114,13,0,0,0,114,9,0,0,0,114,9, - 0,0,0,114,10,0,0,0,218,11,102,105,110,100,95,109, - 111,100,117,108,101,147,0,0,0,115,8,0,0,0,6,11, - 2,2,4,254,16,3,122,23,122,105,112,105,109,112,111,114, - 116,101,114,46,102,105,110,100,95,109,111,100,117,108,101,99, - 3,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0, - 5,0,0,0,67,0,0,0,115,108,0,0,0,116,0,124, - 0,124,1,131,2,125,3,124,3,100,1,117,1,114,17,116, - 1,106,2,124,1,124,0,124,3,100,2,141,3,83,0,116, - 3,124,0,124,1,131,2,125,4,116,4,124,0,124,4,131, - 2,114,52,124,0,106,5,155,0,116,6,155,0,124,4,155, - 0,157,3,125,5,116,1,106,7,124,1,100,1,100,3,100, - 4,141,3,125,6,124,6,106,8,160,9,124,5,161,1,1, - 0,124,6,83,0,100,1,83,0,41,5,122,107,67,114,101, - 97,116,101,32,97,32,77,111,100,117,108,101,83,112,101,99, - 32,102,111,114,32,116,104,101,32,115,112,101,99,105,102,105, - 101,100,32,109,111,100,117,108,101,46,10,10,32,32,32,32, - 32,32,32,32,82,101,116,117,114,110,115,32,78,111,110,101, - 32,105,102,32,116,104,101,32,109,111,100,117,108,101,32,99, - 97,110,110,111,116,32,98,101,32,102,111,117,110,100,46,10, - 32,32,32,32,32,32,32,32,78,41,1,218,10,105,115,95, - 112,97,99,107,97,103,101,84,41,3,218,4,110,97,109,101, - 90,6,108,111,97,100,101,114,114,46,0,0,0,41,10,114, - 38,0,0,0,218,10,95,98,111,111,116,115,116,114,97,112, - 90,16,115,112,101,99,95,102,114,111,109,95,108,111,97,100, - 101,114,114,39,0,0,0,114,40,0,0,0,114,29,0,0, - 0,114,20,0,0,0,90,10,77,111,100,117,108,101,83,112, - 101,99,90,26,115,117,98,109,111,100,117,108,101,95,115,101, - 97,114,99,104,95,108,111,99,97,116,105,111,110,115,114,24, - 0,0,0,41,7,114,32,0,0,0,114,41,0,0,0,90, - 6,116,97,114,103,101,116,90,11,109,111,100,117,108,101,95, - 105,110,102,111,114,43,0,0,0,114,13,0,0,0,90,4, - 115,112,101,99,114,9,0,0,0,114,9,0,0,0,114,10, - 0,0,0,218,9,102,105,110,100,95,115,112,101,99,163,0, - 0,0,115,24,0,0,0,10,5,8,1,16,1,10,7,10, - 1,18,4,8,1,2,1,6,255,12,2,4,1,4,2,122, - 21,122,105,112,105,109,112,111,114,116,101,114,46,102,105,110, - 100,95,115,112,101,99,99,2,0,0,0,0,0,0,0,0, - 0,0,0,5,0,0,0,3,0,0,0,67,0,0,0,115, - 20,0,0,0,116,0,124,0,124,1,131,2,92,3,125,2, - 125,3,125,4,124,2,83,0,41,1,122,166,103,101,116,95, - 99,111,100,101,40,102,117,108,108,110,97,109,101,41,32,45, - 62,32,99,111,100,101,32,111,98,106,101,99,116,46,10,10, - 32,32,32,32,32,32,32,32,82,101,116,117,114,110,32,116, - 104,101,32,99,111,100,101,32,111,98,106,101,99,116,32,102, - 111,114,32,116,104,101,32,115,112,101,99,105,102,105,101,100, - 32,109,111,100,117,108,101,46,32,82,97,105,115,101,32,90, - 105,112,73,109,112,111,114,116,69,114,114,111,114,10,32,32, - 32,32,32,32,32,32,105,102,32,116,104,101,32,109,111,100, - 117,108,101,32,99,111,117,108,100,110,39,116,32,98,101,32, - 105,109,112,111,114,116,101,100,46,10,32,32,32,32,32,32, - 32,32,169,1,218,16,95,103,101,116,95,109,111,100,117,108, - 101,95,99,111,100,101,169,5,114,32,0,0,0,114,41,0, - 0,0,218,4,99,111,100,101,218,9,105,115,112,97,99,107, - 97,103,101,114,43,0,0,0,114,9,0,0,0,114,9,0, - 0,0,114,10,0,0,0,218,8,103,101,116,95,99,111,100, - 101,190,0,0,0,115,4,0,0,0,16,6,4,1,122,20, - 122,105,112,105,109,112,111,114,116,101,114,46,103,101,116,95, - 99,111,100,101,99,2,0,0,0,0,0,0,0,0,0,0, - 0,4,0,0,0,8,0,0,0,67,0,0,0,115,112,0, - 0,0,116,0,114,8,124,1,160,1,116,0,116,2,161,2, - 125,1,124,1,125,2,124,1,160,3,124,0,106,4,116,2, - 23,0,161,1,114,29,124,1,116,5,124,0,106,4,116,2, - 23,0,131,1,100,1,133,2,25,0,125,2,122,7,124,0, - 106,6,124,2,25,0,125,3,87,0,110,13,4,0,116,7, - 121,49,1,0,1,0,1,0,116,8,100,2,100,3,124,2, - 131,3,130,1,119,0,116,9,124,0,106,4,124,3,131,2, - 83,0,41,4,122,154,103,101,116,95,100,97,116,97,40,112, - 97,116,104,110,97,109,101,41,32,45,62,32,115,116,114,105, - 110,103,32,119,105,116,104,32,102,105,108,101,32,100,97,116, - 97,46,10,10,32,32,32,32,32,32,32,32,82,101,116,117, - 114,110,32,116,104,101,32,100,97,116,97,32,97,115,115,111, - 99,105,97,116,101,100,32,119,105,116,104,32,39,112,97,116, - 104,110,97,109,101,39,46,32,82,97,105,115,101,32,79,83, - 69,114,114,111,114,32,105,102,10,32,32,32,32,32,32,32, - 32,116,104,101,32,102,105,108,101,32,119,97,115,110,39,116, - 32,102,111,117,110,100,46,10,32,32,32,32,32,32,32,32, - 78,114,0,0,0,0,218,0,41,10,114,18,0,0,0,114, - 19,0,0,0,114,20,0,0,0,218,10,115,116,97,114,116, - 115,119,105,116,104,114,29,0,0,0,218,3,108,101,110,114, - 28,0,0,0,114,26,0,0,0,114,22,0,0,0,218,9, - 95,103,101,116,95,100,97,116,97,41,4,114,32,0,0,0, - 218,8,112,97,116,104,110,97,109,101,90,3,107,101,121,218, - 9,116,111,99,95,101,110,116,114,121,114,9,0,0,0,114, - 9,0,0,0,114,10,0,0,0,218,8,103,101,116,95,100, - 97,116,97,200,0,0,0,115,22,0,0,0,4,6,12,1, - 4,2,16,1,22,1,2,2,14,1,12,1,12,1,2,255, - 12,2,122,20,122,105,112,105,109,112,111,114,116,101,114,46, - 103,101,116,95,100,97,116,97,99,2,0,0,0,0,0,0, - 0,0,0,0,0,5,0,0,0,3,0,0,0,67,0,0, - 0,115,20,0,0,0,116,0,124,0,124,1,131,2,92,3, - 125,2,125,3,125,4,124,4,83,0,41,1,122,165,103,101, - 116,95,102,105,108,101,110,97,109,101,40,102,117,108,108,110, - 97,109,101,41,32,45,62,32,102,105,108,101,110,97,109,101, - 32,115,116,114,105,110,103,46,10,10,32,32,32,32,32,32, - 32,32,82,101,116,117,114,110,32,116,104,101,32,102,105,108, - 101,110,97,109,101,32,102,111,114,32,116,104,101,32,115,112, - 101,99,105,102,105,101,100,32,109,111,100,117,108,101,32,111, - 114,32,114,97,105,115,101,32,90,105,112,73,109,112,111,114, - 116,69,114,114,111,114,10,32,32,32,32,32,32,32,32,105, - 102,32,105,116,32,99,111,117,108,100,110,39,116,32,98,101, - 32,105,109,112,111,114,116,101,100,46,10,32,32,32,32,32, - 32,32,32,114,50,0,0,0,114,52,0,0,0,114,9,0, - 0,0,114,9,0,0,0,114,10,0,0,0,218,12,103,101, - 116,95,102,105,108,101,110,97,109,101,221,0,0,0,115,4, - 0,0,0,16,8,4,1,122,24,122,105,112,105,109,112,111, - 114,116,101,114,46,103,101,116,95,102,105,108,101,110,97,109, - 101,99,2,0,0,0,0,0,0,0,0,0,0,0,6,0, - 0,0,8,0,0,0,67,0,0,0,115,126,0,0,0,116, - 0,124,0,124,1,131,2,125,2,124,2,100,1,117,0,114, - 18,116,1,100,2,124,1,155,2,157,2,124,1,100,3,141, - 2,130,1,116,2,124,0,124,1,131,2,125,3,124,2,114, - 32,116,3,160,4,124,3,100,4,161,2,125,4,110,5,124, - 3,155,0,100,5,157,2,125,4,122,7,124,0,106,5,124, - 4,25,0,125,5,87,0,110,10,4,0,116,6,121,54,1, - 0,1,0,1,0,89,0,100,1,83,0,119,0,116,7,124, - 0,106,8,124,5,131,2,160,9,161,0,83,0,41,6,122, - 253,103,101,116,95,115,111,117,114,99,101,40,102,117,108,108, - 110,97,109,101,41,32,45,62,32,115,111,117,114,99,101,32, - 115,116,114,105,110,103,46,10,10,32,32,32,32,32,32,32, - 32,82,101,116,117,114,110,32,116,104,101,32,115,111,117,114, - 99,101,32,99,111,100,101,32,102,111,114,32,116,104,101,32, - 115,112,101,99,105,102,105,101,100,32,109,111,100,117,108,101, - 46,32,82,97,105,115,101,32,90,105,112,73,109,112,111,114, - 116,69,114,114,111,114,10,32,32,32,32,32,32,32,32,105, - 102,32,116,104,101,32,109,111,100,117,108,101,32,99,111,117, - 108,100,110,39,116,32,98,101,32,102,111,117,110,100,44,32, - 114,101,116,117,114,110,32,78,111,110,101,32,105,102,32,116, - 104,101,32,97,114,99,104,105,118,101,32,100,111,101,115,10, - 32,32,32,32,32,32,32,32,99,111,110,116,97,105,110,32, - 116,104,101,32,109,111,100,117,108,101,44,32,98,117,116,32, - 104,97,115,32,110,111,32,115,111,117,114,99,101,32,102,111, - 114,32,105,116,46,10,32,32,32,32,32,32,32,32,78,250, - 18,99,97,110,39,116,32,102,105,110,100,32,109,111,100,117, - 108,101,32,169,1,114,47,0,0,0,250,11,95,95,105,110, - 105,116,95,95,46,112,121,250,3,46,112,121,41,10,114,38, - 0,0,0,114,3,0,0,0,114,39,0,0,0,114,21,0, - 0,0,114,30,0,0,0,114,28,0,0,0,114,26,0,0, - 0,114,59,0,0,0,114,29,0,0,0,218,6,100,101,99, - 111,100,101,41,6,114,32,0,0,0,114,41,0,0,0,114, - 42,0,0,0,114,13,0,0,0,218,8,102,117,108,108,112, - 97,116,104,114,61,0,0,0,114,9,0,0,0,114,9,0, - 0,0,114,10,0,0,0,218,10,103,101,116,95,115,111,117, - 114,99,101,233,0,0,0,115,26,0,0,0,10,7,8,1, - 18,1,10,2,4,1,14,1,10,2,2,2,14,1,12,1, - 6,2,2,254,16,3,122,22,122,105,112,105,109,112,111,114, - 116,101,114,46,103,101,116,95,115,111,117,114,99,101,99,2, - 0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,4, - 0,0,0,67,0,0,0,115,40,0,0,0,116,0,124,0, - 124,1,131,2,125,2,124,2,100,1,117,0,114,18,116,1, - 100,2,124,1,155,2,157,2,124,1,100,3,141,2,130,1, - 124,2,83,0,41,4,122,171,105,115,95,112,97,99,107,97, - 103,101,40,102,117,108,108,110,97,109,101,41,32,45,62,32, - 98,111,111,108,46,10,10,32,32,32,32,32,32,32,32,82, - 101,116,117,114,110,32,84,114,117,101,32,105,102,32,116,104, - 101,32,109,111,100,117,108,101,32,115,112,101,99,105,102,105, - 101,100,32,98,121,32,102,117,108,108,110,97,109,101,32,105, - 115,32,97,32,112,97,99,107,97,103,101,46,10,32,32,32, - 32,32,32,32,32,82,97,105,115,101,32,90,105,112,73,109, - 112,111,114,116,69,114,114,111,114,32,105,102,32,116,104,101, - 32,109,111,100,117,108,101,32,99,111,117,108,100,110,39,116, - 32,98,101,32,102,111,117,110,100,46,10,32,32,32,32,32, - 32,32,32,78,114,64,0,0,0,114,65,0,0,0,41,2, - 114,38,0,0,0,114,3,0,0,0,41,3,114,32,0,0, - 0,114,41,0,0,0,114,42,0,0,0,114,9,0,0,0, - 114,9,0,0,0,114,10,0,0,0,114,46,0,0,0,3, - 1,0,0,115,8,0,0,0,10,6,8,1,18,1,4,1, - 122,22,122,105,112,105,109,112,111,114,116,101,114,46,105,115, - 95,112,97,99,107,97,103,101,99,2,0,0,0,0,0,0, - 0,0,0,0,0,9,0,0,0,8,0,0,0,67,0,0, - 0,115,252,0,0,0,100,1,125,2,116,0,160,1,124,2, - 116,2,161,2,1,0,116,3,124,0,124,1,131,2,92,3, - 125,3,125,4,125,5,116,4,106,5,160,6,124,1,161,1, - 125,6,124,6,100,2,117,0,115,31,116,7,124,6,116,8, - 131,2,115,40,116,8,124,1,131,1,125,6,124,6,116,4, - 106,5,124,1,60,0,124,0,124,6,95,9,122,42,124,4, - 114,62,116,10,124,0,124,1,131,2,125,7,116,11,160,12, - 124,0,106,13,124,7,161,2,125,8,124,8,103,1,124,6, - 95,14,116,15,124,6,100,3,131,2,115,70,116,16,124,6, - 95,16,116,11,160,17,124,6,106,18,124,1,124,5,161,3, - 1,0,116,19,124,3,124,6,106,18,131,2,1,0,87,0, - 110,8,1,0,1,0,1,0,116,4,106,5,124,1,61,0, - 130,0,122,7,116,4,106,5,124,1,25,0,125,6,87,0, - 110,15,4,0,116,20,121,116,1,0,1,0,1,0,116,21, - 100,4,124,1,155,2,100,5,157,3,131,1,130,1,119,0, - 116,22,160,23,100,6,124,1,124,5,161,3,1,0,124,6, - 83,0,41,7,97,64,1,0,0,108,111,97,100,95,109,111, - 100,117,108,101,40,102,117,108,108,110,97,109,101,41,32,45, - 62,32,109,111,100,117,108,101,46,10,10,32,32,32,32,32, - 32,32,32,76,111,97,100,32,116,104,101,32,109,111,100,117, - 108,101,32,115,112,101,99,105,102,105,101,100,32,98,121,32, - 39,102,117,108,108,110,97,109,101,39,46,32,39,102,117,108, - 108,110,97,109,101,39,32,109,117,115,116,32,98,101,32,116, - 104,101,10,32,32,32,32,32,32,32,32,102,117,108,108,121, - 32,113,117,97,108,105,102,105,101,100,32,40,100,111,116,116, - 101,100,41,32,109,111,100,117,108,101,32,110,97,109,101,46, - 32,73,116,32,114,101,116,117,114,110,115,32,116,104,101,32, - 105,109,112,111,114,116,101,100,10,32,32,32,32,32,32,32, - 32,109,111,100,117,108,101,44,32,111,114,32,114,97,105,115, - 101,115,32,90,105,112,73,109,112,111,114,116,69,114,114,111, - 114,32,105,102,32,105,116,32,99,111,117,108,100,32,110,111, - 116,32,98,101,32,105,109,112,111,114,116,101,100,46,10,10, - 32,32,32,32,32,32,32,32,68,101,112,114,101,99,97,116, - 101,100,32,115,105,110,99,101,32,80,121,116,104,111,110,32, - 51,46,49,48,46,32,85,115,101,32,101,120,101,99,95,109, - 111,100,117,108,101,40,41,32,105,110,115,116,101,97,100,46, - 10,32,32,32,32,32,32,32,32,122,114,122,105,112,105,109, - 112,111,114,116,46,122,105,112,105,109,112,111,114,116,101,114, - 46,108,111,97,100,95,109,111,100,117,108,101,40,41,32,105, - 115,32,100,101,112,114,101,99,97,116,101,100,32,97,110,100, - 32,115,108,97,116,101,100,32,102,111,114,32,114,101,109,111, - 118,97,108,32,105,110,32,80,121,116,104,111,110,32,51,46, - 49,50,59,32,117,115,101,32,101,120,101,99,95,109,111,100, - 117,108,101,40,41,32,105,110,115,116,101,97,100,78,218,12, - 95,95,98,117,105,108,116,105,110,115,95,95,122,14,76,111, - 97,100,101,100,32,109,111,100,117,108,101,32,122,25,32,110, - 111,116,32,102,111,117,110,100,32,105,110,32,115,121,115,46, - 109,111,100,117,108,101,115,122,30,105,109,112,111,114,116,32, - 123,125,32,35,32,108,111,97,100,101,100,32,102,114,111,109, - 32,90,105,112,32,123,125,41,24,114,35,0,0,0,114,36, - 0,0,0,114,37,0,0,0,114,51,0,0,0,218,3,115, - 121,115,218,7,109,111,100,117,108,101,115,218,3,103,101,116, - 114,15,0,0,0,218,12,95,109,111,100,117,108,101,95,116, - 121,112,101,218,10,95,95,108,111,97,100,101,114,95,95,114, - 39,0,0,0,114,21,0,0,0,114,30,0,0,0,114,29, - 0,0,0,90,8,95,95,112,97,116,104,95,95,218,7,104, - 97,115,97,116,116,114,114,71,0,0,0,90,14,95,102,105, - 120,95,117,112,95,109,111,100,117,108,101,218,8,95,95,100, - 105,99,116,95,95,218,4,101,120,101,99,114,26,0,0,0, - 218,11,73,109,112,111,114,116,69,114,114,111,114,114,48,0, - 0,0,218,16,95,118,101,114,98,111,115,101,95,109,101,115, - 115,97,103,101,41,9,114,32,0,0,0,114,41,0,0,0, - 218,3,109,115,103,114,53,0,0,0,114,54,0,0,0,114, - 43,0,0,0,90,3,109,111,100,114,13,0,0,0,114,69, - 0,0,0,114,9,0,0,0,114,9,0,0,0,114,10,0, - 0,0,218,11,108,111,97,100,95,109,111,100,117,108,101,16, - 1,0,0,115,54,0,0,0,4,9,12,2,16,1,12,1, - 18,1,8,1,10,1,6,1,2,2,4,1,10,3,14,1, - 8,1,10,2,6,1,16,1,16,1,6,1,8,1,2,1, - 2,2,14,1,12,1,16,1,2,255,14,2,4,1,122,23, - 122,105,112,105,109,112,111,114,116,101,114,46,108,111,97,100, - 95,109,111,100,117,108,101,99,2,0,0,0,0,0,0,0, - 0,0,0,0,3,0,0,0,8,0,0,0,67,0,0,0, - 115,64,0,0,0,122,10,124,0,160,0,124,1,161,1,115, - 9,87,0,100,1,83,0,87,0,110,10,4,0,116,1,121, - 20,1,0,1,0,1,0,89,0,100,1,83,0,119,0,100, - 2,100,3,108,2,109,3,125,2,1,0,124,2,124,0,124, - 1,131,2,83,0,41,4,122,204,82,101,116,117,114,110,32, - 116,104,101,32,82,101,115,111,117,114,99,101,82,101,97,100, - 101,114,32,102,111,114,32,97,32,112,97,99,107,97,103,101, - 32,105,110,32,97,32,122,105,112,32,102,105,108,101,46,10, - 10,32,32,32,32,32,32,32,32,73,102,32,39,102,117,108, - 108,110,97,109,101,39,32,105,115,32,97,32,112,97,99,107, - 97,103,101,32,119,105,116,104,105,110,32,116,104,101,32,122, - 105,112,32,102,105,108,101,44,32,114,101,116,117,114,110,32, - 116,104,101,10,32,32,32,32,32,32,32,32,39,82,101,115, - 111,117,114,99,101,82,101,97,100,101,114,39,32,111,98,106, - 101,99,116,32,102,111,114,32,116,104,101,32,112,97,99,107, - 97,103,101,46,32,32,79,116,104,101,114,119,105,115,101,32, - 114,101,116,117,114,110,32,78,111,110,101,46,10,32,32,32, - 32,32,32,32,32,78,114,0,0,0,0,41,1,218,9,90, - 105,112,82,101,97,100,101,114,41,4,114,46,0,0,0,114, - 3,0,0,0,90,17,105,109,112,111,114,116,108,105,98,46, - 114,101,97,100,101,114,115,114,84,0,0,0,41,3,114,32, - 0,0,0,114,41,0,0,0,114,84,0,0,0,114,9,0, - 0,0,114,9,0,0,0,114,10,0,0,0,218,19,103,101, - 116,95,114,101,115,111,117,114,99,101,95,114,101,97,100,101, - 114,59,1,0,0,115,18,0,0,0,2,6,10,1,6,1, - 4,255,12,2,6,1,2,255,12,2,10,1,122,31,122,105, - 112,105,109,112,111,114,116,101,114,46,103,101,116,95,114,101, - 115,111,117,114,99,101,95,114,101,97,100,101,114,99,1,0, - 0,0,0,0,0,0,0,0,0,0,1,0,0,0,8,0, - 0,0,67,0,0,0,115,72,0,0,0,122,15,116,0,124, - 0,106,1,131,1,124,0,95,2,124,0,106,2,116,3,124, - 0,106,1,60,0,87,0,100,1,83,0,4,0,116,4,121, - 35,1,0,1,0,1,0,116,3,160,5,124,0,106,1,100, - 1,161,2,1,0,105,0,124,0,95,2,89,0,100,1,83, - 0,119,0,41,2,122,41,82,101,108,111,97,100,32,116,104, - 101,32,102,105,108,101,32,100,97,116,97,32,111,102,32,116, - 104,101,32,97,114,99,104,105,118,101,32,112,97,116,104,46, - 78,41,6,114,27,0,0,0,114,29,0,0,0,114,28,0, - 0,0,114,25,0,0,0,114,3,0,0,0,218,3,112,111, - 112,169,1,114,32,0,0,0,114,9,0,0,0,114,9,0, - 0,0,114,10,0,0,0,218,17,105,110,118,97,108,105,100, - 97,116,101,95,99,97,99,104,101,115,74,1,0,0,115,14, - 0,0,0,2,2,12,1,18,1,12,1,14,1,12,1,2, - 254,122,29,122,105,112,105,109,112,111,114,116,101,114,46,105, - 110,118,97,108,105,100,97,116,101,95,99,97,99,104,101,115, - 99,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0, - 0,5,0,0,0,67,0,0,0,115,24,0,0,0,100,1, - 124,0,106,0,155,0,116,1,155,0,124,0,106,2,155,0, - 100,2,157,5,83,0,41,3,78,122,21,60,122,105,112,105, - 109,112,111,114,116,101,114,32,111,98,106,101,99,116,32,34, - 122,2,34,62,41,3,114,29,0,0,0,114,20,0,0,0, - 114,31,0,0,0,114,87,0,0,0,114,9,0,0,0,114, - 9,0,0,0,114,10,0,0,0,218,8,95,95,114,101,112, - 114,95,95,84,1,0,0,115,2,0,0,0,24,1,122,20, - 122,105,112,105,109,112,111,114,116,101,114,46,95,95,114,101, - 112,114,95,95,169,1,78,41,17,114,6,0,0,0,114,7, - 0,0,0,114,8,0,0,0,218,7,95,95,100,111,99,95, - 95,114,34,0,0,0,114,44,0,0,0,114,45,0,0,0, - 114,49,0,0,0,114,55,0,0,0,114,62,0,0,0,114, - 63,0,0,0,114,70,0,0,0,114,46,0,0,0,114,83, - 0,0,0,114,85,0,0,0,114,88,0,0,0,114,89,0, - 0,0,114,9,0,0,0,114,9,0,0,0,114,9,0,0, - 0,114,10,0,0,0,114,4,0,0,0,46,0,0,0,115, - 30,0,0,0,8,0,4,1,8,17,10,46,10,37,10,16, - 8,27,8,10,8,21,8,12,8,26,8,13,8,43,8,15, - 12,10,122,12,95,95,105,110,105,116,95,95,46,112,121,99, - 84,114,66,0,0,0,70,41,3,122,4,46,112,121,99,84, - 70,41,3,114,67,0,0,0,70,70,99,2,0,0,0,0, - 0,0,0,0,0,0,0,2,0,0,0,4,0,0,0,67, - 0,0,0,115,20,0,0,0,124,0,106,0,124,1,160,1, - 100,1,161,1,100,2,25,0,23,0,83,0,41,3,78,218, - 1,46,233,2,0,0,0,41,2,114,31,0,0,0,218,10, - 114,112,97,114,116,105,116,105,111,110,41,2,114,32,0,0, - 0,114,41,0,0,0,114,9,0,0,0,114,9,0,0,0, - 114,10,0,0,0,114,39,0,0,0,102,1,0,0,115,2, - 0,0,0,20,1,114,39,0,0,0,99,2,0,0,0,0, - 0,0,0,0,0,0,0,3,0,0,0,2,0,0,0,67, - 0,0,0,115,18,0,0,0,124,1,116,0,23,0,125,2, - 124,2,124,0,106,1,118,0,83,0,114,90,0,0,0,41, - 2,114,20,0,0,0,114,28,0,0,0,41,3,114,32,0, - 0,0,114,13,0,0,0,90,7,100,105,114,112,97,116,104, - 114,9,0,0,0,114,9,0,0,0,114,10,0,0,0,114, - 40,0,0,0,106,1,0,0,115,4,0,0,0,8,4,10, - 2,114,40,0,0,0,99,2,0,0,0,0,0,0,0,0, - 0,0,0,7,0,0,0,4,0,0,0,67,0,0,0,115, - 56,0,0,0,116,0,124,0,124,1,131,2,125,2,116,1, - 68,0,93,18,92,3,125,3,125,4,125,5,124,2,124,3, - 23,0,125,6,124,6,124,0,106,2,118,0,114,25,124,5, - 2,0,1,0,83,0,113,7,100,0,83,0,114,90,0,0, - 0,41,3,114,39,0,0,0,218,16,95,122,105,112,95,115, - 101,97,114,99,104,111,114,100,101,114,114,28,0,0,0,41, - 7,114,32,0,0,0,114,41,0,0,0,114,13,0,0,0, - 218,6,115,117,102,102,105,120,218,10,105,115,98,121,116,101, - 99,111,100,101,114,54,0,0,0,114,69,0,0,0,114,9, - 0,0,0,114,9,0,0,0,114,10,0,0,0,114,38,0, - 0,0,115,1,0,0,115,14,0,0,0,10,1,14,1,8, - 1,10,1,8,1,2,255,4,2,114,38,0,0,0,99,1, - 0,0,0,0,0,0,0,0,0,0,0,26,0,0,0,9, - 0,0,0,67,0,0,0,115,220,4,0,0,122,7,116,0, - 160,1,124,0,161,1,125,1,87,0,110,16,4,0,116,2, - 121,23,1,0,1,0,1,0,116,3,100,1,124,0,155,2, - 157,2,124,0,100,2,141,2,130,1,119,0,124,1,144,2, - 143,65,1,0,122,18,124,1,160,4,116,5,11,0,100,3, - 161,2,1,0,124,1,160,6,161,0,125,2,124,1,160,7, - 116,5,161,1,125,3,87,0,110,16,4,0,116,2,121,62, - 1,0,1,0,1,0,116,3,100,4,124,0,155,2,157,2, - 124,0,100,2,141,2,130,1,119,0,116,8,124,3,131,1, - 116,5,107,3,114,78,116,3,100,4,124,0,155,2,157,2, - 124,0,100,2,141,2,130,1,124,3,100,0,100,5,133,2, - 25,0,116,9,107,3,114,201,122,12,124,1,160,4,100,6, - 100,3,161,2,1,0,124,1,160,6,161,0,125,4,87,0, - 110,16,4,0,116,2,121,114,1,0,1,0,1,0,116,3, - 100,4,124,0,155,2,157,2,124,0,100,2,141,2,130,1, - 119,0,116,10,124,4,116,11,24,0,116,5,24,0,100,6, - 131,2,125,5,122,11,124,1,160,4,124,5,161,1,1,0, - 124,1,160,7,161,0,125,6,87,0,110,16,4,0,116,2, - 121,151,1,0,1,0,1,0,116,3,100,4,124,0,155,2, - 157,2,124,0,100,2,141,2,130,1,119,0,124,6,160,12, - 116,9,161,1,125,7,124,7,100,6,107,0,114,170,116,3, - 100,7,124,0,155,2,157,2,124,0,100,2,141,2,130,1, - 124,6,124,7,124,7,116,5,23,0,133,2,25,0,125,3, - 116,8,124,3,131,1,116,5,107,3,114,193,116,3,100,8, - 124,0,155,2,157,2,124,0,100,2,141,2,130,1,124,4, - 116,8,124,6,131,1,24,0,124,7,23,0,125,2,116,13, - 124,3,100,9,100,10,133,2,25,0,131,1,125,8,116,13, - 124,3,100,10,100,11,133,2,25,0,131,1,125,9,124,2, - 124,8,107,0,114,230,116,3,100,12,124,0,155,2,157,2, - 124,0,100,2,141,2,130,1,124,2,124,9,107,0,114,243, - 116,3,100,13,124,0,155,2,157,2,124,0,100,2,141,2, - 130,1,124,2,124,8,56,0,125,2,124,2,124,9,24,0, - 125,10,124,10,100,6,107,0,144,1,114,9,116,3,100,14, - 124,0,155,2,157,2,124,0,100,2,141,2,130,1,105,0, - 125,11,100,6,125,12,122,7,124,1,160,4,124,2,161,1, - 1,0,87,0,110,17,4,0,116,2,144,1,121,37,1,0, - 1,0,1,0,116,3,100,4,124,0,155,2,157,2,124,0, - 100,2,141,2,130,1,119,0,9,0,124,1,160,7,100,16, - 161,1,125,3,116,8,124,3,131,1,100,5,107,0,144,1, - 114,55,116,14,100,17,131,1,130,1,124,3,100,0,100,5, - 133,2,25,0,100,18,107,3,144,1,114,66,144,1,110,19, - 116,8,124,3,131,1,100,16,107,3,144,1,114,77,116,14, - 100,17,131,1,130,1,116,15,124,3,100,19,100,20,133,2, - 25,0,131,1,125,13,116,15,124,3,100,20,100,9,133,2, - 25,0,131,1,125,14,116,15,124,3,100,9,100,21,133,2, - 25,0,131,1,125,15,116,15,124,3,100,21,100,10,133,2, - 25,0,131,1,125,16,116,13,124,3,100,10,100,11,133,2, - 25,0,131,1,125,17,116,13,124,3,100,11,100,22,133,2, - 25,0,131,1,125,18,116,13,124,3,100,22,100,23,133,2, - 25,0,131,1,125,4,116,15,124,3,100,23,100,24,133,2, - 25,0,131,1,125,19,116,15,124,3,100,24,100,25,133,2, - 25,0,131,1,125,20,116,15,124,3,100,25,100,26,133,2, - 25,0,131,1,125,21,116,13,124,3,100,27,100,16,133,2, - 25,0,131,1,125,22,124,19,124,20,23,0,124,21,23,0, - 125,8,124,22,124,9,107,4,144,1,114,185,116,3,100,28, - 124,0,155,2,157,2,124,0,100,2,141,2,130,1,124,22, - 124,10,55,0,125,22,122,7,124,1,160,7,124,19,161,1, - 125,23,87,0,110,17,4,0,116,2,144,1,121,213,1,0, - 1,0,1,0,116,3,100,4,124,0,155,2,157,2,124,0, - 100,2,141,2,130,1,119,0,116,8,124,23,131,1,124,19, - 107,3,144,1,114,230,116,3,100,4,124,0,155,2,157,2, - 124,0,100,2,141,2,130,1,122,25,116,8,124,1,160,7, - 124,8,124,19,24,0,161,1,131,1,124,8,124,19,24,0, - 107,3,144,1,114,254,116,3,100,4,124,0,155,2,157,2, - 124,0,100,2,141,2,130,1,87,0,110,17,4,0,116,2, - 144,2,121,16,1,0,1,0,1,0,116,3,100,4,124,0, - 155,2,157,2,124,0,100,2,141,2,130,1,119,0,124,13, - 100,29,64,0,144,2,114,27,124,23,160,16,161,0,125,23, - 110,26,122,7,124,23,160,16,100,30,161,1,125,23,87,0, - 110,18,4,0,116,17,144,2,121,52,1,0,1,0,1,0, - 124,23,160,16,100,31,161,1,160,18,116,19,161,1,125,23, - 89,0,110,1,119,0,124,23,160,20,100,32,116,21,161,2, - 125,23,116,22,160,23,124,0,124,23,161,2,125,24,124,24, - 124,14,124,18,124,4,124,22,124,15,124,16,124,17,102,8, - 125,25,124,25,124,11,124,23,60,0,124,12,100,33,55,0, - 125,12,144,1,113,39,87,0,100,0,4,0,4,0,131,3, - 1,0,110,9,49,0,144,2,115,96,119,1,1,0,1,0, - 1,0,89,0,1,0,116,24,160,25,100,34,124,12,124,0, - 161,3,1,0,124,11,83,0,41,35,78,122,21,99,97,110, - 39,116,32,111,112,101,110,32,90,105,112,32,102,105,108,101, - 58,32,114,12,0,0,0,114,93,0,0,0,250,21,99,97, - 110,39,116,32,114,101,97,100,32,90,105,112,32,102,105,108, - 101,58,32,233,4,0,0,0,114,0,0,0,0,122,16,110, - 111,116,32,97,32,90,105,112,32,102,105,108,101,58,32,122, - 18,99,111,114,114,117,112,116,32,90,105,112,32,102,105,108, - 101,58,32,233,12,0,0,0,233,16,0,0,0,233,20,0, - 0,0,122,28,98,97,100,32,99,101,110,116,114,97,108,32, - 100,105,114,101,99,116,111,114,121,32,115,105,122,101,58,32, - 122,30,98,97,100,32,99,101,110,116,114,97,108,32,100,105, - 114,101,99,116,111,114,121,32,111,102,102,115,101,116,58,32, - 122,38,98,97,100,32,99,101,110,116,114,97,108,32,100,105, - 114,101,99,116,111,114,121,32,115,105,122,101,32,111,114,32, - 111,102,102,115,101,116,58,32,84,233,46,0,0,0,250,27, - 69,79,70,32,114,101,97,100,32,119,104,101,114,101,32,110, - 111,116,32,101,120,112,101,99,116,101,100,115,4,0,0,0, - 80,75,1,2,233,8,0,0,0,233,10,0,0,0,233,14, - 0,0,0,233,24,0,0,0,233,28,0,0,0,233,30,0, - 0,0,233,32,0,0,0,233,34,0,0,0,233,42,0,0, - 0,122,25,98,97,100,32,108,111,99,97,108,32,104,101,97, - 100,101,114,32,111,102,102,115,101,116,58,32,105,0,8,0, - 0,218,5,97,115,99,105,105,90,6,108,97,116,105,110,49, - 250,1,47,114,5,0,0,0,122,33,122,105,112,105,109,112, - 111,114,116,58,32,102,111,117,110,100,32,123,125,32,110,97, - 109,101,115,32,105,110,32,123,33,114,125,41,26,218,3,95, - 105,111,218,9,111,112,101,110,95,99,111,100,101,114,22,0, - 0,0,114,3,0,0,0,218,4,115,101,101,107,218,20,69, - 78,68,95,67,69,78,84,82,65,76,95,68,73,82,95,83, - 73,90,69,90,4,116,101,108,108,218,4,114,101,97,100,114, - 58,0,0,0,218,18,83,84,82,73,78,71,95,69,78,68, - 95,65,82,67,72,73,86,69,218,3,109,97,120,218,15,77, - 65,88,95,67,79,77,77,69,78,84,95,76,69,78,218,5, - 114,102,105,110,100,114,2,0,0,0,218,8,69,79,70,69, - 114,114,111,114,114,1,0,0,0,114,68,0,0,0,218,18, - 85,110,105,99,111,100,101,68,101,99,111,100,101,69,114,114, - 111,114,218,9,116,114,97,110,115,108,97,116,101,218,11,99, - 112,52,51,55,95,116,97,98,108,101,114,19,0,0,0,114, - 20,0,0,0,114,21,0,0,0,114,30,0,0,0,114,48, - 0,0,0,114,81,0,0,0,41,26,114,29,0,0,0,218, - 2,102,112,90,15,104,101,97,100,101,114,95,112,111,115,105, - 116,105,111,110,218,6,98,117,102,102,101,114,218,9,102,105, - 108,101,95,115,105,122,101,90,17,109,97,120,95,99,111,109, - 109,101,110,116,95,115,116,97,114,116,218,4,100,97,116,97, - 90,3,112,111,115,218,11,104,101,97,100,101,114,95,115,105, - 122,101,90,13,104,101,97,100,101,114,95,111,102,102,115,101, - 116,90,10,97,114,99,95,111,102,102,115,101,116,114,33,0, - 0,0,218,5,99,111,117,110,116,218,5,102,108,97,103,115, - 218,8,99,111,109,112,114,101,115,115,218,4,116,105,109,101, - 218,4,100,97,116,101,218,3,99,114,99,218,9,100,97,116, - 97,95,115,105,122,101,218,9,110,97,109,101,95,115,105,122, - 101,218,10,101,120,116,114,97,95,115,105,122,101,90,12,99, - 111,109,109,101,110,116,95,115,105,122,101,218,11,102,105,108, - 101,95,111,102,102,115,101,116,114,47,0,0,0,114,13,0, - 0,0,218,1,116,114,9,0,0,0,114,9,0,0,0,114, - 10,0,0,0,114,27,0,0,0,146,1,0,0,115,238,0, - 0,0,2,1,14,1,12,1,18,1,2,255,8,3,2,1, - 14,1,8,1,14,1,12,1,18,1,2,255,12,2,18,1, - 16,1,2,3,12,1,12,1,12,1,10,1,2,1,6,255, - 2,255,8,3,2,1,2,255,2,1,4,255,2,2,10,1, - 12,1,12,1,10,1,2,1,6,255,2,255,10,3,8,1, - 10,1,2,1,6,255,16,2,12,1,10,1,2,1,6,255, - 16,2,16,2,16,1,8,1,18,1,8,1,18,1,8,1, - 8,1,10,1,18,1,4,2,4,2,2,1,14,1,14,1, - 18,1,2,255,2,2,10,1,14,1,8,1,18,2,4,1, - 14,1,8,1,16,1,16,1,16,1,16,1,16,1,16,1, - 16,1,16,1,16,1,16,1,16,1,12,1,10,1,18,1, - 8,1,2,2,14,1,14,1,18,1,2,255,14,2,18,1, - 2,4,28,1,18,1,4,255,14,2,18,1,2,255,10,3, - 10,2,2,3,14,1,14,1,20,1,2,255,12,3,12,1, - 20,1,8,1,8,1,4,202,2,6,30,196,14,109,4,1, - 114,27,0,0,0,117,190,1,0,0,0,1,2,3,4,5, - 6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21, - 22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37, - 38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53, - 54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69, - 70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85, - 86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101, - 102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117, - 118,119,120,121,122,123,124,125,126,127,195,135,195,188,195,169, - 195,162,195,164,195,160,195,165,195,167,195,170,195,171,195,168, - 195,175,195,174,195,172,195,132,195,133,195,137,195,166,195,134, - 195,180,195,182,195,178,195,187,195,185,195,191,195,150,195,156, - 194,162,194,163,194,165,226,130,167,198,146,195,161,195,173,195, - 179,195,186,195,177,195,145,194,170,194,186,194,191,226,140,144, - 194,172,194,189,194,188,194,161,194,171,194,187,226,150,145,226, - 150,146,226,150,147,226,148,130,226,148,164,226,149,161,226,149, - 162,226,149,150,226,149,149,226,149,163,226,149,145,226,149,151, - 226,149,157,226,149,156,226,149,155,226,148,144,226,148,148,226, - 148,180,226,148,172,226,148,156,226,148,128,226,148,188,226,149, - 158,226,149,159,226,149,154,226,149,148,226,149,169,226,149,166, - 226,149,160,226,149,144,226,149,172,226,149,167,226,149,168,226, - 149,164,226,149,165,226,149,153,226,149,152,226,149,146,226,149, - 147,226,149,171,226,149,170,226,148,152,226,148,140,226,150,136, - 226,150,132,226,150,140,226,150,144,226,150,128,206,177,195,159, - 206,147,207,128,206,163,207,131,194,181,207,132,206,166,206,152, - 206,169,206,180,226,136,158,207,134,206,181,226,136,169,226,137, - 161,194,177,226,137,165,226,137,164,226,140,160,226,140,161,195, - 183,226,137,136,194,176,226,136,153,194,183,226,136,154,226,129, - 191,194,178,226,150,160,194,160,99,0,0,0,0,0,0,0, - 0,0,0,0,0,1,0,0,0,8,0,0,0,67,0,0, - 0,115,106,0,0,0,116,0,114,11,116,1,160,2,100,1, - 161,1,1,0,116,3,100,2,131,1,130,1,100,3,97,0, - 122,29,122,8,100,4,100,5,108,4,109,5,125,0,1,0, - 87,0,110,16,4,0,116,6,121,38,1,0,1,0,1,0, - 116,1,160,2,100,1,161,1,1,0,116,3,100,2,131,1, - 130,1,119,0,87,0,100,6,97,0,110,3,100,6,97,0, - 119,0,116,1,160,2,100,7,161,1,1,0,124,0,83,0, - 41,8,78,122,27,122,105,112,105,109,112,111,114,116,58,32, - 122,108,105,98,32,85,78,65,86,65,73,76,65,66,76,69, - 250,41,99,97,110,39,116,32,100,101,99,111,109,112,114,101, - 115,115,32,100,97,116,97,59,32,122,108,105,98,32,110,111, - 116,32,97,118,97,105,108,97,98,108,101,84,114,0,0,0, - 0,169,1,218,10,100,101,99,111,109,112,114,101,115,115,70, - 122,25,122,105,112,105,109,112,111,114,116,58,32,122,108,105, - 98,32,97,118,97,105,108,97,98,108,101,41,7,218,15,95, - 105,109,112,111,114,116,105,110,103,95,122,108,105,98,114,48, - 0,0,0,114,81,0,0,0,114,3,0,0,0,90,4,122, - 108,105,98,114,147,0,0,0,218,9,69,120,99,101,112,116, - 105,111,110,114,146,0,0,0,114,9,0,0,0,114,9,0, - 0,0,114,10,0,0,0,218,20,95,103,101,116,95,100,101, - 99,111,109,112,114,101,115,115,95,102,117,110,99,48,2,0, - 0,115,28,0,0,0,4,2,10,3,8,1,4,2,4,1, - 16,1,12,1,10,1,8,1,2,254,2,255,12,5,10,2, - 4,1,114,150,0,0,0,99,2,0,0,0,0,0,0,0, - 0,0,0,0,17,0,0,0,9,0,0,0,67,0,0,0, - 115,120,1,0,0,124,1,92,8,125,2,125,3,125,4,125, - 5,125,6,125,7,125,8,125,9,124,4,100,1,107,0,114, - 18,116,0,100,2,131,1,130,1,116,1,160,2,124,0,161, - 1,143,129,125,10,122,7,124,10,160,3,124,6,161,1,1, - 0,87,0,110,16,4,0,116,4,121,47,1,0,1,0,1, - 0,116,0,100,3,124,0,155,2,157,2,124,0,100,4,141, - 2,130,1,119,0,124,10,160,5,100,5,161,1,125,11,116, - 6,124,11,131,1,100,5,107,3,114,63,116,7,100,6,131, - 1,130,1,124,11,100,0,100,7,133,2,25,0,100,8,107, - 3,114,80,116,0,100,9,124,0,155,2,157,2,124,0,100, - 4,141,2,130,1,116,8,124,11,100,10,100,11,133,2,25, - 0,131,1,125,12,116,8,124,11,100,11,100,5,133,2,25, - 0,131,1,125,13,100,5,124,12,23,0,124,13,23,0,125, - 14,124,6,124,14,55,0,125,6,122,7,124,10,160,3,124, - 6,161,1,1,0,87,0,110,16,4,0,116,4,121,129,1, - 0,1,0,1,0,116,0,100,3,124,0,155,2,157,2,124, - 0,100,4,141,2,130,1,119,0,124,10,160,5,124,4,161, - 1,125,15,116,6,124,15,131,1,124,4,107,3,114,145,116, - 4,100,12,131,1,130,1,87,0,100,0,4,0,4,0,131, - 3,1,0,110,8,49,0,115,155,119,1,1,0,1,0,1, - 0,89,0,1,0,124,3,100,1,107,2,114,166,124,15,83, - 0,122,5,116,9,131,0,125,16,87,0,110,11,4,0,116, - 10,121,182,1,0,1,0,1,0,116,0,100,13,131,1,130, - 1,119,0,124,16,124,15,100,14,131,2,83,0,41,15,78, - 114,0,0,0,0,122,18,110,101,103,97,116,105,118,101,32, - 100,97,116,97,32,115,105,122,101,114,98,0,0,0,114,12, - 0,0,0,114,110,0,0,0,114,104,0,0,0,114,99,0, - 0,0,115,4,0,0,0,80,75,3,4,122,23,98,97,100, - 32,108,111,99,97,108,32,102,105,108,101,32,104,101,97,100, - 101,114,58,32,233,26,0,0,0,114,109,0,0,0,122,26, - 122,105,112,105,109,112,111,114,116,58,32,99,97,110,39,116, - 32,114,101,97,100,32,100,97,116,97,114,145,0,0,0,105, - 241,255,255,255,41,11,114,3,0,0,0,114,116,0,0,0, - 114,117,0,0,0,114,118,0,0,0,114,22,0,0,0,114, - 120,0,0,0,114,58,0,0,0,114,125,0,0,0,114,1, - 0,0,0,114,150,0,0,0,114,149,0,0,0,41,17,114, - 29,0,0,0,114,61,0,0,0,90,8,100,97,116,97,112, - 97,116,104,114,136,0,0,0,114,140,0,0,0,114,131,0, - 0,0,114,143,0,0,0,114,137,0,0,0,114,138,0,0, - 0,114,139,0,0,0,114,129,0,0,0,114,130,0,0,0, - 114,141,0,0,0,114,142,0,0,0,114,133,0,0,0,90, - 8,114,97,119,95,100,97,116,97,114,147,0,0,0,114,9, - 0,0,0,114,9,0,0,0,114,10,0,0,0,114,59,0, - 0,0,69,2,0,0,115,72,0,0,0,20,1,8,1,8, - 1,12,2,2,2,14,1,12,1,18,1,2,255,10,2,12, - 1,8,1,16,2,18,2,16,2,16,1,12,1,8,1,2, - 1,14,1,12,1,18,1,2,255,10,2,12,1,8,1,2, - 255,28,233,8,26,4,2,2,3,10,1,12,1,8,1,2, - 255,10,2,114,59,0,0,0,99,2,0,0,0,0,0,0, - 0,0,0,0,0,2,0,0,0,3,0,0,0,67,0,0, - 0,115,16,0,0,0,116,0,124,0,124,1,24,0,131,1, - 100,1,107,1,83,0,41,2,78,114,5,0,0,0,41,1, - 218,3,97,98,115,41,2,90,2,116,49,90,2,116,50,114, - 9,0,0,0,114,9,0,0,0,114,10,0,0,0,218,9, - 95,101,113,95,109,116,105,109,101,115,2,0,0,115,2,0, - 0,0,16,2,114,153,0,0,0,99,5,0,0,0,0,0, - 0,0,0,0,0,0,14,0,0,0,6,0,0,0,67,0, - 0,0,115,254,0,0,0,124,3,124,2,100,1,156,2,125, - 5,116,0,160,1,124,4,124,3,124,5,161,3,125,6,124, - 6,100,2,64,0,100,3,107,3,125,7,124,7,114,63,124, - 6,100,4,64,0,100,3,107,3,125,8,116,2,106,3,100, - 5,107,3,114,62,124,8,115,38,116,2,106,3,100,6,107, - 2,114,62,116,4,124,0,124,2,131,2,125,9,124,9,100, - 0,117,1,114,62,116,2,160,5,116,0,106,6,124,9,161, - 2,125,10,116,0,160,7,124,4,124,10,124,3,124,5,161, - 4,1,0,110,40,116,8,124,0,124,2,131,2,92,2,125, - 11,125,12,124,11,114,103,116,9,116,10,124,4,100,7,100, - 8,133,2,25,0,131,1,124,11,131,2,114,93,116,10,124, - 4,100,8,100,9,133,2,25,0,131,1,124,12,107,3,114, - 103,116,11,160,12,100,10,124,3,155,2,157,2,161,1,1, - 0,100,0,83,0,116,13,160,14,124,4,100,9,100,0,133, - 2,25,0,161,1,125,13,116,15,124,13,116,16,131,2,115, - 125,116,17,100,11,124,1,155,2,100,12,157,3,131,1,130, - 1,124,13,83,0,41,13,78,41,2,114,47,0,0,0,114, - 13,0,0,0,114,5,0,0,0,114,0,0,0,0,114,93, - 0,0,0,90,5,110,101,118,101,114,90,6,97,108,119,97, - 121,115,114,105,0,0,0,114,100,0,0,0,114,101,0,0, - 0,122,22,98,121,116,101,99,111,100,101,32,105,115,32,115, - 116,97,108,101,32,102,111,114,32,122,16,99,111,109,112,105, - 108,101,100,32,109,111,100,117,108,101,32,122,21,32,105,115, - 32,110,111,116,32,97,32,99,111,100,101,32,111,98,106,101, - 99,116,41,18,114,21,0,0,0,90,13,95,99,108,97,115, - 115,105,102,121,95,112,121,99,218,4,95,105,109,112,90,21, - 99,104,101,99,107,95,104,97,115,104,95,98,97,115,101,100, - 95,112,121,99,115,218,15,95,103,101,116,95,112,121,99,95, - 115,111,117,114,99,101,218,11,115,111,117,114,99,101,95,104, - 97,115,104,90,17,95,82,65,87,95,77,65,71,73,67,95, - 78,85,77,66,69,82,90,18,95,118,97,108,105,100,97,116, - 101,95,104,97,115,104,95,112,121,99,218,29,95,103,101,116, - 95,109,116,105,109,101,95,97,110,100,95,115,105,122,101,95, - 111,102,95,115,111,117,114,99,101,114,153,0,0,0,114,2, - 0,0,0,114,48,0,0,0,114,81,0,0,0,218,7,109, - 97,114,115,104,97,108,90,5,108,111,97,100,115,114,15,0, - 0,0,218,10,95,99,111,100,101,95,116,121,112,101,218,9, - 84,121,112,101,69,114,114,111,114,41,14,114,32,0,0,0, - 114,60,0,0,0,114,69,0,0,0,114,41,0,0,0,114, - 132,0,0,0,90,11,101,120,99,95,100,101,116,97,105,108, - 115,114,135,0,0,0,90,10,104,97,115,104,95,98,97,115, - 101,100,90,12,99,104,101,99,107,95,115,111,117,114,99,101, - 90,12,115,111,117,114,99,101,95,98,121,116,101,115,114,156, - 0,0,0,90,12,115,111,117,114,99,101,95,109,116,105,109, - 101,90,11,115,111,117,114,99,101,95,115,105,122,101,114,53, - 0,0,0,114,9,0,0,0,114,9,0,0,0,114,10,0, - 0,0,218,15,95,117,110,109,97,114,115,104,97,108,95,99, - 111,100,101,123,2,0,0,115,72,0,0,0,2,2,2,1, - 6,254,14,5,12,2,4,1,12,1,10,1,2,1,2,255, - 8,1,2,255,10,2,8,1,4,1,4,1,2,1,4,254, - 4,5,8,1,4,255,2,128,8,4,6,255,4,3,22,3, - 18,1,2,255,4,2,8,1,4,255,4,2,18,2,10,1, - 16,1,4,1,114,161,0,0,0,99,1,0,0,0,0,0, - 0,0,0,0,0,0,1,0,0,0,4,0,0,0,67,0, - 0,0,115,28,0,0,0,124,0,160,0,100,1,100,2,161, - 2,125,0,124,0,160,0,100,3,100,2,161,2,125,0,124, - 0,83,0,41,4,78,115,2,0,0,0,13,10,243,1,0, - 0,0,10,243,1,0,0,0,13,41,1,114,19,0,0,0, - 41,1,218,6,115,111,117,114,99,101,114,9,0,0,0,114, - 9,0,0,0,114,10,0,0,0,218,23,95,110,111,114,109, - 97,108,105,122,101,95,108,105,110,101,95,101,110,100,105,110, - 103,115,168,2,0,0,115,6,0,0,0,12,1,12,1,4, - 1,114,165,0,0,0,99,2,0,0,0,0,0,0,0,0, - 0,0,0,2,0,0,0,6,0,0,0,67,0,0,0,115, - 24,0,0,0,116,0,124,1,131,1,125,1,116,1,124,1, - 124,0,100,1,100,2,100,3,141,4,83,0,41,4,78,114, - 79,0,0,0,84,41,1,90,12,100,111,110,116,95,105,110, - 104,101,114,105,116,41,2,114,165,0,0,0,218,7,99,111, - 109,112,105,108,101,41,2,114,60,0,0,0,114,164,0,0, - 0,114,9,0,0,0,114,9,0,0,0,114,10,0,0,0, - 218,15,95,99,111,109,112,105,108,101,95,115,111,117,114,99, - 101,175,2,0,0,115,4,0,0,0,8,1,16,1,114,167, - 0,0,0,99,2,0,0,0,0,0,0,0,0,0,0,0, - 2,0,0,0,11,0,0,0,67,0,0,0,115,68,0,0, - 0,116,0,160,1,124,0,100,1,63,0,100,2,23,0,124, - 0,100,3,63,0,100,4,64,0,124,0,100,5,64,0,124, - 1,100,6,63,0,124,1,100,3,63,0,100,7,64,0,124, - 1,100,5,64,0,100,8,20,0,100,9,100,9,100,9,102, - 9,161,1,83,0,41,10,78,233,9,0,0,0,105,188,7, - 0,0,233,5,0,0,0,233,15,0,0,0,233,31,0,0, - 0,233,11,0,0,0,233,63,0,0,0,114,93,0,0,0, - 114,14,0,0,0,41,2,114,137,0,0,0,90,6,109,107, - 116,105,109,101,41,2,218,1,100,114,144,0,0,0,114,9, - 0,0,0,114,9,0,0,0,114,10,0,0,0,218,14,95, - 112,97,114,115,101,95,100,111,115,116,105,109,101,181,2,0, - 0,115,18,0,0,0,4,1,10,1,10,1,6,1,6,1, - 10,1,10,1,6,1,6,249,114,175,0,0,0,99,2,0, - 0,0,0,0,0,0,0,0,0,0,6,0,0,0,10,0, - 0,0,67,0,0,0,115,110,0,0,0,122,41,124,1,100, - 1,100,0,133,2,25,0,100,2,118,0,115,11,74,0,130, - 1,124,1,100,0,100,1,133,2,25,0,125,1,124,0,106, - 0,124,1,25,0,125,2,124,2,100,3,25,0,125,3,124, - 2,100,4,25,0,125,4,124,2,100,5,25,0,125,5,116, - 1,124,4,124,3,131,2,124,5,102,2,87,0,83,0,4, - 0,116,2,116,3,116,4,102,3,121,54,1,0,1,0,1, - 0,89,0,100,6,83,0,119,0,41,7,78,114,14,0,0, - 0,169,2,218,1,99,218,1,111,114,169,0,0,0,233,6, - 0,0,0,233,3,0,0,0,41,2,114,0,0,0,0,114, - 0,0,0,0,41,5,114,28,0,0,0,114,175,0,0,0, - 114,26,0,0,0,218,10,73,110,100,101,120,69,114,114,111, - 114,114,160,0,0,0,41,6,114,32,0,0,0,114,13,0, - 0,0,114,61,0,0,0,114,137,0,0,0,114,138,0,0, - 0,90,17,117,110,99,111,109,112,114,101,115,115,101,100,95, - 115,105,122,101,114,9,0,0,0,114,9,0,0,0,114,10, - 0,0,0,114,157,0,0,0,194,2,0,0,115,22,0,0, - 0,2,1,20,2,12,1,10,1,8,3,8,1,8,1,16, - 1,18,1,6,1,2,255,114,157,0,0,0,99,2,0,0, - 0,0,0,0,0,0,0,0,0,3,0,0,0,8,0,0, - 0,67,0,0,0,115,80,0,0,0,124,1,100,1,100,0, - 133,2,25,0,100,2,118,0,115,10,74,0,130,1,124,1, - 100,0,100,1,133,2,25,0,125,1,122,7,124,0,106,0, - 124,1,25,0,125,2,87,0,110,10,4,0,116,1,121,33, - 1,0,1,0,1,0,89,0,100,0,83,0,119,0,116,2, - 124,0,106,3,124,2,131,2,83,0,41,3,78,114,14,0, - 0,0,114,176,0,0,0,41,4,114,28,0,0,0,114,26, - 0,0,0,114,59,0,0,0,114,29,0,0,0,41,3,114, - 32,0,0,0,114,13,0,0,0,114,61,0,0,0,114,9, - 0,0,0,114,9,0,0,0,114,10,0,0,0,114,155,0, - 0,0,213,2,0,0,115,16,0,0,0,20,2,12,1,2, - 2,14,1,12,1,6,1,2,255,12,3,114,155,0,0,0, - 99,2,0,0,0,0,0,0,0,0,0,0,0,14,0,0, - 0,11,0,0,0,67,0,0,0,115,14,1,0,0,116,0, - 124,0,124,1,131,2,125,2,100,0,125,3,116,1,68,0, - 93,102,92,3,125,4,125,5,125,6,124,2,124,4,23,0, - 125,7,116,2,106,3,100,1,124,0,106,4,116,5,124,7, - 100,2,100,3,141,5,1,0,122,7,124,0,106,6,124,7, - 25,0,125,8,87,0,110,9,4,0,116,7,121,45,1,0, - 1,0,1,0,89,0,113,9,119,0,124,8,100,4,25,0, - 125,9,116,8,124,0,106,4,124,8,131,2,125,10,100,0, - 125,11,124,5,114,91,122,10,116,9,124,0,124,9,124,7, - 124,1,124,10,131,5,125,11,87,0,110,25,4,0,116,10, - 121,90,1,0,125,12,1,0,122,8,124,12,125,3,87,0, - 89,0,100,0,125,12,126,12,110,10,100,0,125,12,126,12, - 119,1,119,0,116,11,124,9,124,10,131,2,125,11,124,11, - 100,0,117,0,114,101,113,9,124,8,100,4,25,0,125,9, - 124,11,124,6,124,9,102,3,2,0,1,0,83,0,124,3, - 114,126,100,5,124,3,155,0,157,2,125,13,116,12,124,13, - 124,1,100,6,141,2,124,3,130,2,116,12,100,7,124,1, - 155,2,157,2,124,1,100,6,141,2,130,1,41,8,78,122, - 13,116,114,121,105,110,103,32,123,125,123,125,123,125,114,93, - 0,0,0,41,1,90,9,118,101,114,98,111,115,105,116,121, - 114,0,0,0,0,122,20,109,111,100,117,108,101,32,108,111, - 97,100,32,102,97,105,108,101,100,58,32,114,65,0,0,0, - 114,64,0,0,0,41,13,114,39,0,0,0,114,95,0,0, - 0,114,48,0,0,0,114,81,0,0,0,114,29,0,0,0, - 114,20,0,0,0,114,28,0,0,0,114,26,0,0,0,114, - 59,0,0,0,114,161,0,0,0,114,80,0,0,0,114,167, - 0,0,0,114,3,0,0,0,41,14,114,32,0,0,0,114, - 41,0,0,0,114,13,0,0,0,90,12,105,109,112,111,114, - 116,95,101,114,114,111,114,114,96,0,0,0,114,97,0,0, - 0,114,54,0,0,0,114,69,0,0,0,114,61,0,0,0, - 114,43,0,0,0,114,132,0,0,0,114,53,0,0,0,90, - 3,101,120,99,114,82,0,0,0,114,9,0,0,0,114,9, - 0,0,0,114,10,0,0,0,114,51,0,0,0,228,2,0, - 0,115,58,0,0,0,10,1,4,1,14,1,8,1,22,1, - 2,1,14,1,12,1,4,1,2,255,8,3,12,1,4,1, - 4,1,2,1,20,1,14,1,16,1,8,128,2,255,10,3, - 8,1,2,3,8,1,14,1,4,2,10,1,14,1,18,2, - 114,51,0,0,0,41,46,114,91,0,0,0,90,26,95,102, - 114,111,122,101,110,95,105,109,112,111,114,116,108,105,98,95, - 101,120,116,101,114,110,97,108,114,21,0,0,0,114,1,0, - 0,0,114,2,0,0,0,90,17,95,102,114,111,122,101,110, - 95,105,109,112,111,114,116,108,105,98,114,48,0,0,0,114, - 154,0,0,0,114,116,0,0,0,114,158,0,0,0,114,72, - 0,0,0,114,137,0,0,0,114,35,0,0,0,90,7,95, - 95,97,108,108,95,95,114,20,0,0,0,90,15,112,97,116, - 104,95,115,101,112,97,114,97,116,111,114,115,114,18,0,0, - 0,114,80,0,0,0,114,3,0,0,0,114,25,0,0,0, - 218,4,116,121,112,101,114,75,0,0,0,114,119,0,0,0, - 114,121,0,0,0,114,123,0,0,0,90,13,95,76,111,97, - 100,101,114,66,97,115,105,99,115,114,4,0,0,0,114,95, - 0,0,0,114,39,0,0,0,114,40,0,0,0,114,38,0, - 0,0,114,27,0,0,0,114,128,0,0,0,114,148,0,0, - 0,114,150,0,0,0,114,59,0,0,0,114,153,0,0,0, - 114,161,0,0,0,218,8,95,95,99,111,100,101,95,95,114, - 159,0,0,0,114,165,0,0,0,114,167,0,0,0,114,175, - 0,0,0,114,157,0,0,0,114,155,0,0,0,114,51,0, - 0,0,114,9,0,0,0,114,9,0,0,0,114,9,0,0, - 0,114,10,0,0,0,218,8,60,109,111,100,117,108,101,62, - 1,0,0,0,115,90,0,0,0,4,0,8,16,16,1,8, - 1,8,1,8,1,8,1,8,1,8,1,8,1,8,2,6, - 3,14,1,16,3,4,4,8,2,4,2,4,1,4,1,18, - 2,0,127,0,127,12,50,12,1,2,1,2,1,4,252,8, - 9,8,4,8,9,8,31,2,126,2,254,4,29,8,5,8, - 21,8,46,8,8,10,40,8,5,8,7,8,6,8,13,8, - 19,12,15, -}; diff --git a/contrib/tools/python3/src/Python/initconfig.c b/contrib/tools/python3/src/Python/initconfig.c deleted file mode 100644 index e0b65e86678..00000000000 --- a/contrib/tools/python3/src/Python/initconfig.c +++ /dev/null @@ -1,3058 +0,0 @@ -#include "Python.h" -#include "pycore_fileutils.h" // _Py_HasFileSystemDefaultEncodeErrors -#include "pycore_getopt.h" // _PyOS_GetOpt() -#include "pycore_initconfig.h" // _PyStatus_OK() -#include "pycore_interp.h" // _PyInterpreterState.runtime -#include "pycore_pathconfig.h" // _Py_path_config -#include "pycore_pyerrors.h" // _PyErr_Fetch() -#include "pycore_pylifecycle.h" // _Py_PreInitializeFromConfig() -#include "pycore_pymem.h" // _PyMem_SetDefaultAllocator() -#include "pycore_pystate.h" // _PyThreadState_GET() - -#include "osdefs.h" // DELIM -#include <locale.h> // setlocale() -#if defined(MS_WINDOWS) || defined(__CYGWIN__) -# ifdef HAVE_IO_H -# include <io.h> -# endif -# ifdef HAVE_FCNTL_H -# include <fcntl.h> // O_BINARY -# endif -#endif - -#ifndef PLATLIBDIR -# error "PLATLIBDIR macro must be defined" -#endif - - -/* --- Command line options --------------------------------------- */ - -/* Short usage message (with %s for argv0) */ -static const char usage_line[] = -"usage: %ls [option] ... [-c cmd | -m mod | file | -] [arg] ...\n"; - -/* Long usage message, split into parts < 512 bytes */ -static const char usage_1[] = "\ -Options and arguments (and corresponding environment variables):\n\ --b : issue warnings about str(bytes_instance), str(bytearray_instance)\n\ - and comparing bytes/bytearray with str. (-bb: issue errors)\n\ --B : don't write .pyc files on import; also PYTHONDONTWRITEBYTECODE=x\n\ --c cmd : program passed in as string (terminates option list)\n\ --d : turn on parser debugging output (for experts only, only works on\n\ - debug builds); also PYTHONDEBUG=x\n\ --E : ignore PYTHON* environment variables (such as PYTHONPATH)\n\ --h : print this help message and exit (also -? or --help)\n\ -"; -static const char usage_2[] = "\ --i : inspect interactively after running script; forces a prompt even\n\ - if stdin does not appear to be a terminal; also PYTHONINSPECT=x\n\ --I : isolate Python from the user's environment (implies -E and -s)\n\ --m mod : run library module as a script (terminates option list)\n\ --O : remove assert and __debug__-dependent statements; add .opt-1 before\n\ - .pyc extension; also PYTHONOPTIMIZE=x\n\ --OO : do -O changes and also discard docstrings; add .opt-2 before\n\ - .pyc extension\n\ --q : don't print version and copyright messages on interactive startup\n\ --s : don't add user site directory to sys.path; also PYTHONNOUSERSITE\n\ --S : don't imply 'import site' on initialization\n\ -"; -static const char usage_3[] = "\ --u : force the stdout and stderr streams to be unbuffered;\n\ - this option has no effect on stdin; also PYTHONUNBUFFERED=x\n\ --v : verbose (trace import statements); also PYTHONVERBOSE=x\n\ - can be supplied multiple times to increase verbosity\n\ --V : print the Python version number and exit (also --version)\n\ - when given twice, print more information about the build\n\ --W arg : warning control; arg is action:message:category:module:lineno\n\ - also PYTHONWARNINGS=arg\n\ --x : skip first line of source, allowing use of non-Unix forms of #!cmd\n\ --X opt : set implementation-specific option. The following options are available:\n\ - -X faulthandler: enable faulthandler\n\ - -X showrefcount: output the total reference count and number of used\n\ - memory blocks when the program finishes or after each statement in the\n\ - interactive interpreter. This only works on debug builds\n\ - -X tracemalloc: start tracing Python memory allocations using the\n\ - tracemalloc module. By default, only the most recent frame is stored in a\n\ - traceback of a trace. Use -X tracemalloc=NFRAME to start tracing with a\n\ - traceback limit of NFRAME frames\n\ - -X importtime: show how long each import takes. It shows module name,\n\ - cumulative time (including nested imports) and self time (excluding\n\ - nested imports). Note that its output may be broken in multi-threaded\n\ - application. Typical usage is python3 -X importtime -c 'import asyncio'\n\ - -X dev: enable CPython's \"development mode\", introducing additional runtime\n\ - checks which are too expensive to be enabled by default. Effect of the\n\ - developer mode:\n\ - * Add default warning filter, as -W default\n\ - * Install debug hooks on memory allocators: see the PyMem_SetupDebugHooks()\n\ - C function\n\ - * Enable the faulthandler module to dump the Python traceback on a crash\n\ - * Enable asyncio debug mode\n\ - * Set the dev_mode attribute of sys.flags to True\n\ - * io.IOBase destructor logs close() exceptions\n\ - -X utf8: enable UTF-8 mode for operating system interfaces, overriding the default\n\ - locale-aware mode. -X utf8=0 explicitly disables UTF-8 mode (even when it would\n\ - otherwise activate automatically)\n\ - -X pycache_prefix=PATH: enable writing .pyc files to a parallel tree rooted at the\n\ - given directory instead of to the code tree\n\ - -X warn_default_encoding: enable opt-in EncodingWarning for 'encoding=None'\n\ ---check-hash-based-pycs always|default|never:\n\ - control how Python invalidates hash-based .pyc files\n\ -"; -static const char usage_4[] = "\ -file : program read from script file\n\ -- : program read from stdin (default; interactive mode if a tty)\n\ -arg ...: arguments passed to program in sys.argv[1:]\n\n\ -Other environment variables:\n\ -PYTHONSTARTUP: file executed on interactive startup (no default)\n\ -PYTHONPATH : '%lc'-separated list of directories prefixed to the\n\ - default module search path. The result is sys.path.\n\ -"; -static const char usage_5[] = -"PYTHONHOME : alternate <prefix> directory (or <prefix>%lc<exec_prefix>).\n" -" The default module search path uses %s.\n" -"PYTHONPLATLIBDIR : override sys.platlibdir.\n" -"PYTHONCASEOK : ignore case in 'import' statements (Windows).\n" -"PYTHONUTF8: if set to 1, enable the UTF-8 mode.\n" -"PYTHONIOENCODING: Encoding[:errors] used for stdin/stdout/stderr.\n" -"PYTHONFAULTHANDLER: dump the Python traceback on fatal errors.\n"; -static const char usage_6[] = -"PYTHONHASHSEED: if this variable is set to 'random', a random value is used\n" -" to seed the hashes of str and bytes objects. It can also be set to an\n" -" integer in the range [0,4294967295] to get hash values with a\n" -" predictable seed.\n" -"PYTHONMALLOC: set the Python memory allocators and/or install debug hooks\n" -" on Python memory allocators. Use PYTHONMALLOC=debug to install debug\n" -" hooks.\n" -"PYTHONCOERCECLOCALE: if this variable is set to 0, it disables the locale\n" -" coercion behavior. Use PYTHONCOERCECLOCALE=warn to request display of\n" -" locale coercion and locale compatibility warnings on stderr.\n" -"PYTHONBREAKPOINT: if this variable is set to 0, it disables the default\n" -" debugger. It can be set to the callable of your debugger of choice.\n" -"PYTHONDEVMODE: enable the development mode.\n" -"PYTHONPYCACHEPREFIX: root directory for bytecode cache (pyc) files.\n" -"PYTHONWARNDEFAULTENCODING: enable opt-in EncodingWarning for 'encoding=None'.\n"; - -#if defined(MS_WINDOWS) -# define PYTHONHOMEHELP "<prefix>\\python{major}{minor}" -#else -# define PYTHONHOMEHELP "<prefix>/lib/pythonX.X" -#endif - - -/* --- Global configuration variables ----------------------------- */ - -/* UTF-8 mode (PEP 540): if equals to 1, use the UTF-8 encoding, and change - stdin and stdout error handler to "surrogateescape". */ -int Py_UTF8Mode = 0; -int Py_DebugFlag = 0; /* Needed by parser.c */ -int Py_VerboseFlag = 0; /* Needed by import.c */ -int Py_QuietFlag = 0; /* Needed by sysmodule.c */ -int Py_InteractiveFlag = 0; /* Needed by Py_FdIsInteractive() below */ -int Py_InspectFlag = 0; /* Needed to determine whether to exit at SystemExit */ -int Py_OptimizeFlag = 0; /* Needed by compile.c */ -int Py_NoSiteFlag = 0; /* Suppress 'import site' */ -int Py_BytesWarningFlag = 0; /* Warn on str(bytes) and str(buffer) */ -int Py_FrozenFlag = 1; /* Needed by getpath.c */ -int Py_IgnoreEnvironmentFlag = 0; /* e.g. PYTHONPATH, PYTHONHOME */ -int Py_DontWriteBytecodeFlag = 0; /* Suppress writing bytecode files (*.pyc) */ -int Py_NoUserSiteDirectory = 0; /* for -s and site.py */ -int Py_UnbufferedStdioFlag = 0; /* Unbuffered binary std{in,out,err} */ -int Py_HashRandomizationFlag = 0; /* for -R and PYTHONHASHSEED */ -int Py_IsolatedFlag = 0; /* for -I, isolate from user's env */ -#ifdef MS_WINDOWS -int Py_LegacyWindowsFSEncodingFlag = 0; /* Uses mbcs instead of utf-8 */ -int Py_LegacyWindowsStdioFlag = 0; /* Uses FileIO instead of WindowsConsoleIO */ -#endif - - -static PyObject * -_Py_GetGlobalVariablesAsDict(void) -{ - PyObject *dict, *obj; - - dict = PyDict_New(); - if (dict == NULL) { - return NULL; - } - -#define SET_ITEM(KEY, EXPR) \ - do { \ - obj = (EXPR); \ - if (obj == NULL) { \ - return NULL; \ - } \ - int res = PyDict_SetItemString(dict, (KEY), obj); \ - Py_DECREF(obj); \ - if (res < 0) { \ - goto fail; \ - } \ - } while (0) -#define SET_ITEM_INT(VAR) \ - SET_ITEM(#VAR, PyLong_FromLong(VAR)) -#define FROM_STRING(STR) \ - ((STR != NULL) ? \ - PyUnicode_FromString(STR) \ - : (Py_INCREF(Py_None), Py_None)) -#define SET_ITEM_STR(VAR) \ - SET_ITEM(#VAR, FROM_STRING(VAR)) - - SET_ITEM_STR(Py_FileSystemDefaultEncoding); - SET_ITEM_INT(Py_HasFileSystemDefaultEncoding); - SET_ITEM_STR(Py_FileSystemDefaultEncodeErrors); - SET_ITEM_INT(_Py_HasFileSystemDefaultEncodeErrors); - - SET_ITEM_INT(Py_UTF8Mode); - SET_ITEM_INT(Py_DebugFlag); - SET_ITEM_INT(Py_VerboseFlag); - SET_ITEM_INT(Py_QuietFlag); - SET_ITEM_INT(Py_InteractiveFlag); - SET_ITEM_INT(Py_InspectFlag); - - SET_ITEM_INT(Py_OptimizeFlag); - SET_ITEM_INT(Py_NoSiteFlag); - SET_ITEM_INT(Py_BytesWarningFlag); - SET_ITEM_INT(Py_FrozenFlag); - SET_ITEM_INT(Py_IgnoreEnvironmentFlag); - SET_ITEM_INT(Py_DontWriteBytecodeFlag); - SET_ITEM_INT(Py_NoUserSiteDirectory); - SET_ITEM_INT(Py_UnbufferedStdioFlag); - SET_ITEM_INT(Py_HashRandomizationFlag); - SET_ITEM_INT(Py_IsolatedFlag); - -#ifdef MS_WINDOWS - SET_ITEM_INT(Py_LegacyWindowsFSEncodingFlag); - SET_ITEM_INT(Py_LegacyWindowsStdioFlag); -#endif - - return dict; - -fail: - Py_DECREF(dict); - return NULL; - -#undef FROM_STRING -#undef SET_ITEM -#undef SET_ITEM_INT -#undef SET_ITEM_STR -} - - -/* --- PyStatus ----------------------------------------------- */ - -PyStatus PyStatus_Ok(void) -{ return _PyStatus_OK(); } - -PyStatus PyStatus_Error(const char *err_msg) -{ - assert(err_msg != NULL); - return (PyStatus){._type = _PyStatus_TYPE_ERROR, - .err_msg = err_msg}; -} - -PyStatus PyStatus_NoMemory(void) -{ return PyStatus_Error("memory allocation failed"); } - -PyStatus PyStatus_Exit(int exitcode) -{ return _PyStatus_EXIT(exitcode); } - - -int PyStatus_IsError(PyStatus status) -{ return _PyStatus_IS_ERROR(status); } - -int PyStatus_IsExit(PyStatus status) -{ return _PyStatus_IS_EXIT(status); } - -int PyStatus_Exception(PyStatus status) -{ return _PyStatus_EXCEPTION(status); } - -PyObject* -_PyErr_SetFromPyStatus(PyStatus status) -{ - if (!_PyStatus_IS_ERROR(status)) { - PyErr_Format(PyExc_SystemError, - "%s() expects an error PyStatus", - _PyStatus_GET_FUNC()); - } - else if (status.func) { - PyErr_Format(PyExc_ValueError, "%s: %s", status.func, status.err_msg); - } - else { - PyErr_Format(PyExc_ValueError, "%s", status.err_msg); - } - return NULL; -} - - -/* --- PyWideStringList ------------------------------------------------ */ - -#ifndef NDEBUG -int -_PyWideStringList_CheckConsistency(const PyWideStringList *list) -{ - assert(list->length >= 0); - if (list->length != 0) { - assert(list->items != NULL); - } - for (Py_ssize_t i = 0; i < list->length; i++) { - assert(list->items[i] != NULL); - } - return 1; -} -#endif /* Py_DEBUG */ - - -void -_PyWideStringList_Clear(PyWideStringList *list) -{ - assert(_PyWideStringList_CheckConsistency(list)); - for (Py_ssize_t i=0; i < list->length; i++) { - PyMem_RawFree(list->items[i]); - } - PyMem_RawFree(list->items); - list->length = 0; - list->items = NULL; -} - - -int -_PyWideStringList_Copy(PyWideStringList *list, const PyWideStringList *list2) -{ - assert(_PyWideStringList_CheckConsistency(list)); - assert(_PyWideStringList_CheckConsistency(list2)); - - if (list2->length == 0) { - _PyWideStringList_Clear(list); - return 0; - } - - PyWideStringList copy = _PyWideStringList_INIT; - - size_t size = list2->length * sizeof(list2->items[0]); - copy.items = PyMem_RawMalloc(size); - if (copy.items == NULL) { - return -1; - } - - for (Py_ssize_t i=0; i < list2->length; i++) { - wchar_t *item = _PyMem_RawWcsdup(list2->items[i]); - if (item == NULL) { - _PyWideStringList_Clear(©); - return -1; - } - copy.items[i] = item; - copy.length = i + 1; - } - - _PyWideStringList_Clear(list); - *list = copy; - return 0; -} - - -PyStatus -PyWideStringList_Insert(PyWideStringList *list, - Py_ssize_t index, const wchar_t *item) -{ - Py_ssize_t len = list->length; - if (len == PY_SSIZE_T_MAX) { - /* length+1 would overflow */ - return _PyStatus_NO_MEMORY(); - } - if (index < 0) { - return _PyStatus_ERR("PyWideStringList_Insert index must be >= 0"); - } - if (index > len) { - index = len; - } - - wchar_t *item2 = _PyMem_RawWcsdup(item); - if (item2 == NULL) { - return _PyStatus_NO_MEMORY(); - } - - size_t size = (len + 1) * sizeof(list->items[0]); - wchar_t **items2 = (wchar_t **)PyMem_RawRealloc(list->items, size); - if (items2 == NULL) { - PyMem_RawFree(item2); - return _PyStatus_NO_MEMORY(); - } - - if (index < len) { - memmove(&items2[index + 1], - &items2[index], - (len - index) * sizeof(items2[0])); - } - - items2[index] = item2; - list->items = items2; - list->length++; - return _PyStatus_OK(); -} - - -PyStatus -PyWideStringList_Append(PyWideStringList *list, const wchar_t *item) -{ - return PyWideStringList_Insert(list, list->length, item); -} - - -PyStatus -_PyWideStringList_Extend(PyWideStringList *list, const PyWideStringList *list2) -{ - for (Py_ssize_t i = 0; i < list2->length; i++) { - PyStatus status = PyWideStringList_Append(list, list2->items[i]); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - } - return _PyStatus_OK(); -} - - -static int -_PyWideStringList_Find(PyWideStringList *list, const wchar_t *item) -{ - for (Py_ssize_t i = 0; i < list->length; i++) { - if (wcscmp(list->items[i], item) == 0) { - return 1; - } - } - return 0; -} - - -PyObject* -_PyWideStringList_AsList(const PyWideStringList *list) -{ - assert(_PyWideStringList_CheckConsistency(list)); - - PyObject *pylist = PyList_New(list->length); - if (pylist == NULL) { - return NULL; - } - - for (Py_ssize_t i = 0; i < list->length; i++) { - PyObject *item = PyUnicode_FromWideChar(list->items[i], -1); - if (item == NULL) { - Py_DECREF(pylist); - return NULL; - } - PyList_SET_ITEM(pylist, i, item); - } - return pylist; -} - - -/* --- Py_SetStandardStreamEncoding() ----------------------------- */ - -/* Helper to allow an embedding application to override the normal - * mechanism that attempts to figure out an appropriate IO encoding - */ - -static char *_Py_StandardStreamEncoding = NULL; -static char *_Py_StandardStreamErrors = NULL; - -int -Py_SetStandardStreamEncoding(const char *encoding, const char *errors) -{ - if (Py_IsInitialized()) { - /* This is too late to have any effect */ - return -1; - } - - int res = 0; - - /* Py_SetStandardStreamEncoding() can be called before Py_Initialize(), - but Py_Initialize() can change the allocator. Use a known allocator - to be able to release the memory later. */ - PyMemAllocatorEx old_alloc; - _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - - /* Can't call PyErr_NoMemory() on errors, as Python hasn't been - * initialised yet. - * - * However, the raw memory allocators are initialised appropriately - * as C static variables, so _PyMem_RawStrdup is OK even though - * Py_Initialize hasn't been called yet. - */ - if (encoding) { - PyMem_RawFree(_Py_StandardStreamEncoding); - _Py_StandardStreamEncoding = _PyMem_RawStrdup(encoding); - if (!_Py_StandardStreamEncoding) { - res = -2; - goto done; - } - } - if (errors) { - PyMem_RawFree(_Py_StandardStreamErrors); - _Py_StandardStreamErrors = _PyMem_RawStrdup(errors); - if (!_Py_StandardStreamErrors) { - PyMem_RawFree(_Py_StandardStreamEncoding); - _Py_StandardStreamEncoding = NULL; - res = -3; - goto done; - } - } -#ifdef MS_WINDOWS - if (_Py_StandardStreamEncoding) { - /* Overriding the stream encoding implies legacy streams */ - Py_LegacyWindowsStdioFlag = 1; - } -#endif - -done: - PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - - return res; -} - - -void -_Py_ClearStandardStreamEncoding(void) -{ - /* Use the same allocator than Py_SetStandardStreamEncoding() */ - PyMemAllocatorEx old_alloc; - _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - - /* We won't need them anymore. */ - if (_Py_StandardStreamEncoding) { - PyMem_RawFree(_Py_StandardStreamEncoding); - _Py_StandardStreamEncoding = NULL; - } - if (_Py_StandardStreamErrors) { - PyMem_RawFree(_Py_StandardStreamErrors); - _Py_StandardStreamErrors = NULL; - } - - PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); -} - - -/* --- Py_GetArgcArgv() ------------------------------------------- */ - -/* For Py_GetArgcArgv(); set by _Py_SetArgcArgv() */ -static PyWideStringList orig_argv = {.length = 0, .items = NULL}; - - -void -_Py_ClearArgcArgv(void) -{ - PyMemAllocatorEx old_alloc; - _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - - _PyWideStringList_Clear(&orig_argv); - - PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); -} - - -static int -_Py_SetArgcArgv(Py_ssize_t argc, wchar_t * const *argv) -{ - const PyWideStringList argv_list = {.length = argc, .items = (wchar_t **)argv}; - int res; - - PyMemAllocatorEx old_alloc; - _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - - res = _PyWideStringList_Copy(&orig_argv, &argv_list); - - PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - return res; -} - - -// _PyConfig_Write() calls _Py_SetArgcArgv() with PyConfig.orig_argv. -void -Py_GetArgcArgv(int *argc, wchar_t ***argv) -{ - *argc = (int)orig_argv.length; - *argv = orig_argv.items; -} - - -void -Py_InitArgcArgv(int argc, wchar_t **argv) -{ - _Py_SetArgcArgv((Py_ssize_t)argc, argv); -} - -/* --- PyConfig ---------------------------------------------- */ - -#define DECODE_LOCALE_ERR(NAME, LEN) \ - (((LEN) == -2) \ - ? _PyStatus_ERR("cannot decode " NAME) \ - : _PyStatus_NO_MEMORY()) - -#define MAX_HASH_SEED 4294967295UL - - -#ifndef NDEBUG -static int -config_check_consistency(const PyConfig *config) -{ - /* Check config consistency */ - assert(config->isolated >= 0); - assert(config->use_environment >= 0); - assert(config->dev_mode >= 0); - assert(config->install_signal_handlers >= 0); - assert(config->use_hash_seed >= 0); - assert(config->hash_seed <= MAX_HASH_SEED); - assert(config->faulthandler >= 0); - assert(config->tracemalloc >= 0); - assert(config->import_time >= 0); - assert(config->show_ref_count >= 0); - assert(config->dump_refs >= 0); - assert(config->malloc_stats >= 0); - assert(config->site_import >= 0); - assert(config->bytes_warning >= 0); - assert(config->warn_default_encoding >= 0); - assert(config->inspect >= 0); - assert(config->interactive >= 0); - assert(config->optimization_level >= 0); - assert(config->parser_debug >= 0); - assert(config->write_bytecode >= 0); - assert(config->verbose >= 0); - assert(config->quiet >= 0); - assert(config->user_site_directory >= 0); - assert(config->parse_argv >= 0); - assert(config->configure_c_stdio >= 0); - assert(config->buffered_stdio >= 0); - assert(config->program_name != NULL); - assert(_PyWideStringList_CheckConsistency(&config->orig_argv)); - assert(_PyWideStringList_CheckConsistency(&config->argv)); - /* sys.argv must be non-empty: empty argv is replaced with [''] */ - assert(config->argv.length >= 1); - assert(_PyWideStringList_CheckConsistency(&config->xoptions)); - assert(_PyWideStringList_CheckConsistency(&config->warnoptions)); - assert(_PyWideStringList_CheckConsistency(&config->module_search_paths)); - assert(config->module_search_paths_set >= 0); - assert(config->platlibdir != NULL); - assert(config->filesystem_encoding != NULL); - assert(config->filesystem_errors != NULL); - assert(config->stdio_encoding != NULL); - assert(config->stdio_errors != NULL); -#ifdef MS_WINDOWS - assert(config->legacy_windows_stdio >= 0); -#endif - /* -c and -m options are exclusive */ - assert(!(config->run_command != NULL && config->run_module != NULL)); - assert(config->check_hash_pycs_mode != NULL); - assert(config->_install_importlib >= 0); - assert(config->pathconfig_warnings >= 0); - return 1; -} -#endif - - -/* Free memory allocated in config, but don't clear all attributes */ -void -PyConfig_Clear(PyConfig *config) -{ -#define CLEAR(ATTR) \ - do { \ - PyMem_RawFree(ATTR); \ - ATTR = NULL; \ - } while (0) - - CLEAR(config->pycache_prefix); - CLEAR(config->pythonpath_env); - CLEAR(config->home); - CLEAR(config->program_name); - - _PyWideStringList_Clear(&config->argv); - _PyWideStringList_Clear(&config->warnoptions); - _PyWideStringList_Clear(&config->xoptions); - _PyWideStringList_Clear(&config->module_search_paths); - config->module_search_paths_set = 0; - - CLEAR(config->executable); - CLEAR(config->base_executable); - CLEAR(config->prefix); - CLEAR(config->base_prefix); - CLEAR(config->exec_prefix); - CLEAR(config->base_exec_prefix); - CLEAR(config->platlibdir); - - CLEAR(config->filesystem_encoding); - CLEAR(config->filesystem_errors); - CLEAR(config->stdio_encoding); - CLEAR(config->stdio_errors); - CLEAR(config->run_command); - CLEAR(config->run_module); - CLEAR(config->run_filename); - CLEAR(config->check_hash_pycs_mode); - - _PyWideStringList_Clear(&config->orig_argv); -#undef CLEAR -} - - -void -_PyConfig_InitCompatConfig(PyConfig *config) -{ - memset(config, 0, sizeof(*config)); - - config->_config_init = (int)_PyConfig_INIT_COMPAT; - config->isolated = -1; - config->use_environment = -1; - config->dev_mode = -1; - config->install_signal_handlers = 1; - config->use_hash_seed = -1; - config->faulthandler = -1; - config->tracemalloc = -1; - config->module_search_paths_set = 0; - config->parse_argv = 0; - config->site_import = -1; - config->bytes_warning = -1; - config->warn_default_encoding = 0; - config->inspect = -1; - config->interactive = -1; - config->optimization_level = -1; - config->parser_debug= -1; - config->write_bytecode = -1; - config->verbose = -1; - config->quiet = -1; - config->user_site_directory = -1; - config->configure_c_stdio = 0; - config->buffered_stdio = -1; - config->_install_importlib = 1; - config->check_hash_pycs_mode = NULL; - config->pathconfig_warnings = -1; - config->_init_main = 1; - config->_isolated_interpreter = 0; -#ifdef MS_WINDOWS - config->legacy_windows_stdio = -1; -#endif -} - - -static void -config_init_defaults(PyConfig *config) -{ - _PyConfig_InitCompatConfig(config); - - config->isolated = 0; - config->use_environment = 1; - config->site_import = 1; - config->bytes_warning = 0; - config->inspect = 0; - config->interactive = 0; - config->optimization_level = 0; - config->parser_debug= 0; - config->write_bytecode = 1; - config->verbose = 0; - config->quiet = 0; - config->user_site_directory = 1; - config->buffered_stdio = 1; - config->pathconfig_warnings = 1; -#ifdef MS_WINDOWS - config->legacy_windows_stdio = 0; -#endif -} - - -void -PyConfig_InitPythonConfig(PyConfig *config) -{ - config_init_defaults(config); - - config->_config_init = (int)_PyConfig_INIT_PYTHON; - config->configure_c_stdio = 1; - config->parse_argv = 1; -} - - -void -PyConfig_InitIsolatedConfig(PyConfig *config) -{ - config_init_defaults(config); - - config->_config_init = (int)_PyConfig_INIT_ISOLATED; - config->isolated = 1; - config->use_environment = 0; - config->user_site_directory = 0; - config->dev_mode = 0; - config->install_signal_handlers = 0; - config->use_hash_seed = 0; - config->faulthandler = 0; - config->tracemalloc = 0; - config->pathconfig_warnings = 0; -#ifdef MS_WINDOWS - config->legacy_windows_stdio = 0; -#endif -} - - -/* Copy str into *config_str (duplicate the string) */ -PyStatus -PyConfig_SetString(PyConfig *config, wchar_t **config_str, const wchar_t *str) -{ - PyStatus status = _Py_PreInitializeFromConfig(config, NULL); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - wchar_t *str2; - if (str != NULL) { - str2 = _PyMem_RawWcsdup(str); - if (str2 == NULL) { - return _PyStatus_NO_MEMORY(); - } - } - else { - str2 = NULL; - } - PyMem_RawFree(*config_str); - *config_str = str2; - return _PyStatus_OK(); -} - - -static PyStatus -config_set_bytes_string(PyConfig *config, wchar_t **config_str, - const char *str, const char *decode_err_msg) -{ - PyStatus status = _Py_PreInitializeFromConfig(config, NULL); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - wchar_t *str2; - if (str != NULL) { - size_t len; - str2 = Py_DecodeLocale(str, &len); - if (str2 == NULL) { - if (len == (size_t)-2) { - return _PyStatus_ERR(decode_err_msg); - } - else { - return _PyStatus_NO_MEMORY(); - } - } - } - else { - str2 = NULL; - } - PyMem_RawFree(*config_str); - *config_str = str2; - return _PyStatus_OK(); -} - - -#define CONFIG_SET_BYTES_STR(config, config_str, str, NAME) \ - config_set_bytes_string(config, config_str, str, "cannot decode " NAME) - - -/* Decode str using Py_DecodeLocale() and set the result into *config_str. - Pre-initialize Python if needed to ensure that encodings are properly - configured. */ -PyStatus -PyConfig_SetBytesString(PyConfig *config, wchar_t **config_str, - const char *str) -{ - return CONFIG_SET_BYTES_STR(config, config_str, str, "string"); -} - - -PyStatus -_PyConfig_Copy(PyConfig *config, const PyConfig *config2) -{ - PyStatus status; - - PyConfig_Clear(config); - -#define COPY_ATTR(ATTR) config->ATTR = config2->ATTR -#define COPY_WSTR_ATTR(ATTR) \ - do { \ - status = PyConfig_SetString(config, &config->ATTR, config2->ATTR); \ - if (_PyStatus_EXCEPTION(status)) { \ - return status; \ - } \ - } while (0) -#define COPY_WSTRLIST(LIST) \ - do { \ - if (_PyWideStringList_Copy(&config->LIST, &config2->LIST) < 0) { \ - return _PyStatus_NO_MEMORY(); \ - } \ - } while (0) - - COPY_ATTR(_config_init); - COPY_ATTR(isolated); - COPY_ATTR(use_environment); - COPY_ATTR(dev_mode); - COPY_ATTR(install_signal_handlers); - COPY_ATTR(use_hash_seed); - COPY_ATTR(hash_seed); - COPY_ATTR(_install_importlib); - COPY_ATTR(faulthandler); - COPY_ATTR(tracemalloc); - COPY_ATTR(import_time); - COPY_ATTR(show_ref_count); - COPY_ATTR(dump_refs); - COPY_ATTR(malloc_stats); - - COPY_WSTR_ATTR(pycache_prefix); - COPY_WSTR_ATTR(pythonpath_env); - COPY_WSTR_ATTR(home); - COPY_WSTR_ATTR(program_name); - - COPY_ATTR(parse_argv); - COPY_WSTRLIST(argv); - COPY_WSTRLIST(warnoptions); - COPY_WSTRLIST(xoptions); - COPY_WSTRLIST(module_search_paths); - COPY_ATTR(module_search_paths_set); - - COPY_WSTR_ATTR(executable); - COPY_WSTR_ATTR(base_executable); - COPY_WSTR_ATTR(prefix); - COPY_WSTR_ATTR(base_prefix); - COPY_WSTR_ATTR(exec_prefix); - COPY_WSTR_ATTR(base_exec_prefix); - COPY_WSTR_ATTR(platlibdir); - - COPY_ATTR(site_import); - COPY_ATTR(bytes_warning); - COPY_ATTR(warn_default_encoding); - COPY_ATTR(inspect); - COPY_ATTR(interactive); - COPY_ATTR(optimization_level); - COPY_ATTR(parser_debug); - COPY_ATTR(write_bytecode); - COPY_ATTR(verbose); - COPY_ATTR(quiet); - COPY_ATTR(user_site_directory); - COPY_ATTR(configure_c_stdio); - COPY_ATTR(buffered_stdio); - COPY_WSTR_ATTR(filesystem_encoding); - COPY_WSTR_ATTR(filesystem_errors); - COPY_WSTR_ATTR(stdio_encoding); - COPY_WSTR_ATTR(stdio_errors); -#ifdef MS_WINDOWS - COPY_ATTR(legacy_windows_stdio); -#endif - COPY_ATTR(skip_source_first_line); - COPY_WSTR_ATTR(run_command); - COPY_WSTR_ATTR(run_module); - COPY_WSTR_ATTR(run_filename); - COPY_WSTR_ATTR(check_hash_pycs_mode); - COPY_ATTR(pathconfig_warnings); - COPY_ATTR(_init_main); - COPY_ATTR(_isolated_interpreter); - COPY_WSTRLIST(orig_argv); - -#undef COPY_ATTR -#undef COPY_WSTR_ATTR -#undef COPY_WSTRLIST - return _PyStatus_OK(); -} - - -PyObject * -_PyConfig_AsDict(const PyConfig *config) -{ - PyObject *dict = PyDict_New(); - if (dict == NULL) { - return NULL; - } - -#define SET_ITEM(KEY, EXPR) \ - do { \ - PyObject *obj = (EXPR); \ - if (obj == NULL) { \ - goto fail; \ - } \ - int res = PyDict_SetItemString(dict, (KEY), obj); \ - Py_DECREF(obj); \ - if (res < 0) { \ - goto fail; \ - } \ - } while (0) -#define SET_ITEM_INT(ATTR) \ - SET_ITEM(#ATTR, PyLong_FromLong(config->ATTR)) -#define SET_ITEM_UINT(ATTR) \ - SET_ITEM(#ATTR, PyLong_FromUnsignedLong(config->ATTR)) -#define FROM_WSTRING(STR) \ - ((STR != NULL) ? \ - PyUnicode_FromWideChar(STR, -1) \ - : (Py_INCREF(Py_None), Py_None)) -#define SET_ITEM_WSTR(ATTR) \ - SET_ITEM(#ATTR, FROM_WSTRING(config->ATTR)) -#define SET_ITEM_WSTRLIST(LIST) \ - SET_ITEM(#LIST, _PyWideStringList_AsList(&config->LIST)) - - SET_ITEM_INT(_config_init); - SET_ITEM_INT(isolated); - SET_ITEM_INT(use_environment); - SET_ITEM_INT(dev_mode); - SET_ITEM_INT(install_signal_handlers); - SET_ITEM_INT(use_hash_seed); - SET_ITEM_UINT(hash_seed); - SET_ITEM_INT(faulthandler); - SET_ITEM_INT(tracemalloc); - SET_ITEM_INT(import_time); - SET_ITEM_INT(show_ref_count); - SET_ITEM_INT(dump_refs); - SET_ITEM_INT(malloc_stats); - SET_ITEM_WSTR(filesystem_encoding); - SET_ITEM_WSTR(filesystem_errors); - SET_ITEM_WSTR(pycache_prefix); - SET_ITEM_WSTR(program_name); - SET_ITEM_INT(parse_argv); - SET_ITEM_WSTRLIST(argv); - SET_ITEM_WSTRLIST(xoptions); - SET_ITEM_WSTRLIST(warnoptions); - SET_ITEM_WSTR(pythonpath_env); - SET_ITEM_WSTR(home); - SET_ITEM_INT(module_search_paths_set); - SET_ITEM_WSTRLIST(module_search_paths); - SET_ITEM_WSTR(executable); - SET_ITEM_WSTR(base_executable); - SET_ITEM_WSTR(prefix); - SET_ITEM_WSTR(base_prefix); - SET_ITEM_WSTR(exec_prefix); - SET_ITEM_WSTR(base_exec_prefix); - SET_ITEM_WSTR(platlibdir); - SET_ITEM_INT(site_import); - SET_ITEM_INT(bytes_warning); - SET_ITEM_INT(warn_default_encoding); - SET_ITEM_INT(inspect); - SET_ITEM_INT(interactive); - SET_ITEM_INT(optimization_level); - SET_ITEM_INT(parser_debug); - SET_ITEM_INT(write_bytecode); - SET_ITEM_INT(verbose); - SET_ITEM_INT(quiet); - SET_ITEM_INT(user_site_directory); - SET_ITEM_INT(configure_c_stdio); - SET_ITEM_INT(buffered_stdio); - SET_ITEM_WSTR(stdio_encoding); - SET_ITEM_WSTR(stdio_errors); -#ifdef MS_WINDOWS - SET_ITEM_INT(legacy_windows_stdio); -#endif - SET_ITEM_INT(skip_source_first_line); - SET_ITEM_WSTR(run_command); - SET_ITEM_WSTR(run_module); - SET_ITEM_WSTR(run_filename); - SET_ITEM_INT(_install_importlib); - SET_ITEM_WSTR(check_hash_pycs_mode); - SET_ITEM_INT(pathconfig_warnings); - SET_ITEM_INT(_init_main); - SET_ITEM_INT(_isolated_interpreter); - SET_ITEM_WSTRLIST(orig_argv); - - return dict; - -fail: - Py_DECREF(dict); - return NULL; - -#undef FROM_WSTRING -#undef SET_ITEM -#undef SET_ITEM_INT -#undef SET_ITEM_UINT -#undef SET_ITEM_WSTR -#undef SET_ITEM_WSTRLIST -} - - -static PyObject* -config_dict_get(PyObject *dict, const char *name) -{ - PyObject *item = _PyDict_GetItemStringWithError(dict, name); - if (item == NULL && !PyErr_Occurred()) { - PyErr_Format(PyExc_ValueError, "missing config key: %s", name); - return NULL; - } - return item; -} - - -static void -config_dict_invalid_value(const char *name) -{ - PyErr_Format(PyExc_ValueError, "invalid config value: %s", name); -} - - -static void -config_dict_invalid_type(const char *name) -{ - PyErr_Format(PyExc_TypeError, "invalid config type: %s", name); -} - - -static int -config_dict_get_int(PyObject *dict, const char *name, int *result) -{ - PyObject *item = config_dict_get(dict, name); - if (item == NULL) { - return -1; - } - int value = _PyLong_AsInt(item); - if (value == -1 && PyErr_Occurred()) { - if (PyErr_ExceptionMatches(PyExc_TypeError)) { - config_dict_invalid_type(name); - } - else if (PyErr_ExceptionMatches(PyExc_OverflowError)) { - config_dict_invalid_value(name); - } - return -1; - } - *result = value; - return 0; -} - - -static int -config_dict_get_ulong(PyObject *dict, const char *name, unsigned long *result) -{ - PyObject *item = config_dict_get(dict, name); - if (item == NULL) { - return -1; - } - unsigned long value = PyLong_AsUnsignedLong(item); - if (value == (unsigned long)-1 && PyErr_Occurred()) { - if (PyErr_ExceptionMatches(PyExc_TypeError)) { - config_dict_invalid_type(name); - } - else if (PyErr_ExceptionMatches(PyExc_OverflowError)) { - config_dict_invalid_value(name); - } - return -1; - } - *result = value; - return 0; -} - - -static int -config_dict_get_wstr(PyObject *dict, const char *name, PyConfig *config, - wchar_t **result) -{ - PyObject *item = config_dict_get(dict, name); - if (item == NULL) { - return -1; - } - PyStatus status; - if (item == Py_None) { - status = PyConfig_SetString(config, result, NULL); - } - else if (!PyUnicode_Check(item)) { - config_dict_invalid_type(name); - return -1; - } - else { - wchar_t *wstr = PyUnicode_AsWideCharString(item, NULL); - if (wstr == NULL) { - return -1; - } - status = PyConfig_SetString(config, result, wstr); - PyMem_Free(wstr); - } - if (_PyStatus_EXCEPTION(status)) { - PyErr_NoMemory(); - return -1; - } - return 0; -} - - -static int -config_dict_get_wstrlist(PyObject *dict, const char *name, PyConfig *config, - PyWideStringList *result) -{ - PyObject *list = config_dict_get(dict, name); - if (list == NULL) { - return -1; - } - - if (!PyList_CheckExact(list)) { - config_dict_invalid_type(name); - return -1; - } - - PyWideStringList wstrlist = _PyWideStringList_INIT; - for (Py_ssize_t i=0; i < PyList_GET_SIZE(list); i++) { - PyObject *item = PyList_GET_ITEM(list, i); - - if (item == Py_None) { - config_dict_invalid_value(name); - goto error; - } - else if (!PyUnicode_Check(item)) { - config_dict_invalid_type(name); - goto error; - } - wchar_t *wstr = PyUnicode_AsWideCharString(item, NULL); - if (wstr == NULL) { - goto error; - } - PyStatus status = PyWideStringList_Append(&wstrlist, wstr); - PyMem_Free(wstr); - if (_PyStatus_EXCEPTION(status)) { - PyErr_NoMemory(); - goto error; - } - } - - if (_PyWideStringList_Copy(result, &wstrlist) < 0) { - PyErr_NoMemory(); - goto error; - } - _PyWideStringList_Clear(&wstrlist); - return 0; - -error: - _PyWideStringList_Clear(&wstrlist); - return -1; -} - - -int -_PyConfig_FromDict(PyConfig *config, PyObject *dict) -{ - if (!PyDict_Check(dict)) { - PyErr_SetString(PyExc_TypeError, "dict expected"); - return -1; - } - -#define CHECK_VALUE(NAME, TEST) \ - if (!(TEST)) { \ - config_dict_invalid_value(NAME); \ - return -1; \ - } -#define GET_UINT(KEY) \ - do { \ - if (config_dict_get_int(dict, #KEY, &config->KEY) < 0) { \ - return -1; \ - } \ - CHECK_VALUE(#KEY, config->KEY >= 0); \ - } while (0) -#define GET_WSTR(KEY) \ - do { \ - if (config_dict_get_wstr(dict, #KEY, config, &config->KEY) < 0) { \ - return -1; \ - } \ - CHECK_VALUE(#KEY, config->KEY != NULL); \ - } while (0) -#define GET_WSTR_OPT(KEY) \ - do { \ - if (config_dict_get_wstr(dict, #KEY, config, &config->KEY) < 0) { \ - return -1; \ - } \ - } while (0) -#define GET_WSTRLIST(KEY) \ - do { \ - if (config_dict_get_wstrlist(dict, #KEY, config, &config->KEY) < 0) { \ - return -1; \ - } \ - } while (0) - - GET_UINT(_config_init); - CHECK_VALUE("_config_init", - config->_config_init == _PyConfig_INIT_COMPAT - || config->_config_init == _PyConfig_INIT_PYTHON - || config->_config_init == _PyConfig_INIT_ISOLATED); - GET_UINT(isolated); - GET_UINT(use_environment); - GET_UINT(dev_mode); - GET_UINT(install_signal_handlers); - GET_UINT(use_hash_seed); - if (config_dict_get_ulong(dict, "hash_seed", &config->hash_seed) < 0) { - return -1; - } - CHECK_VALUE("hash_seed", config->hash_seed <= MAX_HASH_SEED); - GET_UINT(faulthandler); - GET_UINT(tracemalloc); - GET_UINT(import_time); - GET_UINT(show_ref_count); - GET_UINT(dump_refs); - GET_UINT(malloc_stats); - GET_WSTR(filesystem_encoding); - GET_WSTR(filesystem_errors); - GET_WSTR_OPT(pycache_prefix); - GET_UINT(parse_argv); - GET_WSTRLIST(orig_argv); - GET_WSTRLIST(argv); - GET_WSTRLIST(xoptions); - GET_WSTRLIST(warnoptions); - GET_UINT(site_import); - GET_UINT(bytes_warning); - GET_UINT(warn_default_encoding); - GET_UINT(inspect); - GET_UINT(interactive); - GET_UINT(optimization_level); - GET_UINT(parser_debug); - GET_UINT(write_bytecode); - GET_UINT(verbose); - GET_UINT(quiet); - GET_UINT(user_site_directory); - GET_UINT(configure_c_stdio); - GET_UINT(buffered_stdio); - GET_WSTR(stdio_encoding); - GET_WSTR(stdio_errors); -#ifdef MS_WINDOWS - GET_UINT(legacy_windows_stdio); -#endif - GET_WSTR(check_hash_pycs_mode); - - GET_UINT(pathconfig_warnings); - GET_WSTR(program_name); - GET_WSTR_OPT(pythonpath_env); - GET_WSTR_OPT(home); - GET_WSTR(platlibdir); - - // Path configuration output - GET_UINT(module_search_paths_set); - GET_WSTRLIST(module_search_paths); - GET_WSTR_OPT(executable); - GET_WSTR_OPT(base_executable); - GET_WSTR_OPT(prefix); - GET_WSTR_OPT(base_prefix); - GET_WSTR_OPT(exec_prefix); - GET_WSTR_OPT(base_exec_prefix); - - GET_UINT(skip_source_first_line); - GET_WSTR_OPT(run_command); - GET_WSTR_OPT(run_module); - GET_WSTR_OPT(run_filename); - - GET_UINT(_install_importlib); - GET_UINT(_init_main); - GET_UINT(_isolated_interpreter); - -#undef CHECK_VALUE -#undef GET_UINT -#undef GET_WSTR -#undef GET_WSTR_OPT - return 0; -} - - -static const char* -config_get_env(const PyConfig *config, const char *name) -{ - return _Py_GetEnv(config->use_environment, name); -} - - -/* Get a copy of the environment variable as wchar_t*. - Return 0 on success, but *dest can be NULL. - Return -1 on memory allocation failure. Return -2 on decoding error. */ -static PyStatus -config_get_env_dup(PyConfig *config, - wchar_t **dest, - wchar_t *wname, char *name, - const char *decode_err_msg) -{ - assert(*dest == NULL); - assert(config->use_environment >= 0); - - if (!config->use_environment) { - *dest = NULL; - return _PyStatus_OK(); - } - -#ifdef MS_WINDOWS - const wchar_t *var = _wgetenv(wname); - if (!var || var[0] == '\0') { - *dest = NULL; - return _PyStatus_OK(); - } - - return PyConfig_SetString(config, dest, var); -#else - const char *var = getenv(name); - if (!var || var[0] == '\0') { - *dest = NULL; - return _PyStatus_OK(); - } - - return config_set_bytes_string(config, dest, var, decode_err_msg); -#endif -} - - -#define CONFIG_GET_ENV_DUP(CONFIG, DEST, WNAME, NAME) \ - config_get_env_dup(CONFIG, DEST, WNAME, NAME, "cannot decode " NAME) - - -static void -config_get_global_vars(PyConfig *config) -{ - if (config->_config_init != _PyConfig_INIT_COMPAT) { - /* Python and Isolated configuration ignore global variables */ - return; - } - -#define COPY_FLAG(ATTR, VALUE) \ - if (config->ATTR == -1) { \ - config->ATTR = VALUE; \ - } -#define COPY_NOT_FLAG(ATTR, VALUE) \ - if (config->ATTR == -1) { \ - config->ATTR = !(VALUE); \ - } - - COPY_FLAG(isolated, Py_IsolatedFlag); - COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag); - COPY_FLAG(bytes_warning, Py_BytesWarningFlag); - COPY_FLAG(inspect, Py_InspectFlag); - COPY_FLAG(interactive, Py_InteractiveFlag); - COPY_FLAG(optimization_level, Py_OptimizeFlag); - COPY_FLAG(parser_debug, Py_DebugFlag); - COPY_FLAG(verbose, Py_VerboseFlag); - COPY_FLAG(quiet, Py_QuietFlag); -#ifdef MS_WINDOWS - COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag); -#endif - COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag); - - COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag); - COPY_NOT_FLAG(site_import, Py_NoSiteFlag); - COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag); - COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory); - -#undef COPY_FLAG -#undef COPY_NOT_FLAG -} - - -/* Set Py_xxx global configuration variables from 'config' configuration. */ -static void -config_set_global_vars(const PyConfig *config) -{ -#define COPY_FLAG(ATTR, VAR) \ - if (config->ATTR != -1) { \ - VAR = config->ATTR; \ - } -#define COPY_NOT_FLAG(ATTR, VAR) \ - if (config->ATTR != -1) { \ - VAR = !config->ATTR; \ - } - - COPY_FLAG(isolated, Py_IsolatedFlag); - COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag); - COPY_FLAG(bytes_warning, Py_BytesWarningFlag); - COPY_FLAG(inspect, Py_InspectFlag); - COPY_FLAG(interactive, Py_InteractiveFlag); - COPY_FLAG(optimization_level, Py_OptimizeFlag); - COPY_FLAG(parser_debug, Py_DebugFlag); - COPY_FLAG(verbose, Py_VerboseFlag); - COPY_FLAG(quiet, Py_QuietFlag); -#ifdef MS_WINDOWS - COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag); -#endif - COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag); - - COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag); - COPY_NOT_FLAG(site_import, Py_NoSiteFlag); - COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag); - COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory); - - /* Random or non-zero hash seed */ - Py_HashRandomizationFlag = (config->use_hash_seed == 0 || - config->hash_seed != 0); - -#undef COPY_FLAG -#undef COPY_NOT_FLAG -} - - -/* Get the program name: use PYTHONEXECUTABLE and __PYVENV_LAUNCHER__ - environment variables on macOS if available. */ -static PyStatus -config_init_program_name(PyConfig *config) -{ - PyStatus status; - - /* If Py_SetProgramName() was called, use its value */ - const wchar_t *program_name = _Py_path_config.program_name; - if (program_name != NULL) { - config->program_name = _PyMem_RawWcsdup(program_name); - if (config->program_name == NULL) { - return _PyStatus_NO_MEMORY(); - } - return _PyStatus_OK(); - } - -#ifdef __APPLE__ - /* On MacOS X, when the Python interpreter is embedded in an - application bundle, it gets executed by a bootstrapping script - that does os.execve() with an argv[0] that's different from the - actual Python executable. This is needed to keep the Finder happy, - or rather, to work around Apple's overly strict requirements of - the process name. However, we still need a usable sys.executable, - so the actual executable path is passed in an environment variable. - See Lib/plat-mac/bundlebuilder.py for details about the bootstrap - script. */ - const char *p = config_get_env(config, "PYTHONEXECUTABLE"); - if (p != NULL) { - status = CONFIG_SET_BYTES_STR(config, &config->program_name, p, - "PYTHONEXECUTABLE environment variable"); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - return _PyStatus_OK(); - } -#ifdef WITH_NEXT_FRAMEWORK - else { - const char* pyvenv_launcher = getenv("__PYVENV_LAUNCHER__"); - if (pyvenv_launcher && *pyvenv_launcher) { - /* Used by Mac/Tools/pythonw.c to forward - * the argv0 of the stub executable - */ - status = CONFIG_SET_BYTES_STR(config, - &config->program_name, - pyvenv_launcher, - "__PYVENV_LAUNCHER__ environment variable"); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - /* - * This environment variable is used to communicate between - * the stub launcher and the real interpreter and isn't needed - * beyond this point. - * - * Clean up to avoid problems when launching other programs - * later on. - */ - (void)unsetenv("__PYVENV_LAUNCHER__"); - - return _PyStatus_OK(); - } - } -#endif /* WITH_NEXT_FRAMEWORK */ -#endif /* __APPLE__ */ - - /* Use argv[0] if available and non-empty */ - const PyWideStringList *argv = &config->argv; - if (argv->length >= 1 && argv->items[0][0] != L'\0') { - config->program_name = _PyMem_RawWcsdup(argv->items[0]); - if (config->program_name == NULL) { - return _PyStatus_NO_MEMORY(); - } - return _PyStatus_OK(); - } - - /* Last fall back: hardcoded name */ -#ifdef MS_WINDOWS - const wchar_t *default_program_name = L"python"; -#else - const wchar_t *default_program_name = L"python3"; -#endif - status = PyConfig_SetString(config, &config->program_name, - default_program_name); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - return _PyStatus_OK(); -} - -static PyStatus -config_init_executable(PyConfig *config) -{ - assert(config->executable == NULL); - - /* If Py_SetProgramFullPath() was called, use its value */ - const wchar_t *program_full_path = _Py_path_config.program_full_path; - if (program_full_path != NULL) { - PyStatus status = PyConfig_SetString(config, - &config->executable, - program_full_path); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - return _PyStatus_OK(); - } - return _PyStatus_OK(); -} - - -static const wchar_t* -config_get_xoption(const PyConfig *config, wchar_t *name) -{ - return _Py_get_xoption(&config->xoptions, name); -} - - -static PyStatus -config_init_home(PyConfig *config) -{ - assert(config->home == NULL); - - /* If Py_SetPythonHome() was called, use its value */ - wchar_t *home = _Py_path_config.home; - if (home) { - PyStatus status = PyConfig_SetString(config, &config->home, home); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - return _PyStatus_OK(); - } - - return CONFIG_GET_ENV_DUP(config, &config->home, - L"PYTHONHOME", "PYTHONHOME"); -} - -static PyStatus -config_init_hash_seed(PyConfig *config) -{ - const char *seed_text = config_get_env(config, "PYTHONHASHSEED"); - - Py_BUILD_ASSERT(sizeof(_Py_HashSecret_t) == sizeof(_Py_HashSecret.uc)); - /* Convert a text seed to a numeric one */ - if (seed_text && strcmp(seed_text, "random") != 0) { - const char *endptr = seed_text; - unsigned long seed; - errno = 0; - seed = strtoul(seed_text, (char **)&endptr, 10); - if (*endptr != '\0' - || seed > MAX_HASH_SEED - || (errno == ERANGE && seed == ULONG_MAX)) - { - return _PyStatus_ERR("PYTHONHASHSEED must be \"random\" " - "or an integer in range [0; 4294967295]"); - } - /* Use a specific hash */ - config->use_hash_seed = 1; - config->hash_seed = seed; - } - else { - /* Use a random hash */ - config->use_hash_seed = 0; - config->hash_seed = 0; - } - return _PyStatus_OK(); -} - - -static int -config_wstr_to_int(const wchar_t *wstr, int *result) -{ - const wchar_t *endptr = wstr; - errno = 0; - long value = wcstol(wstr, (wchar_t **)&endptr, 10); - if (*endptr != '\0' || errno == ERANGE) { - return -1; - } - if (value < INT_MIN || value > INT_MAX) { - return -1; - } - - *result = (int)value; - return 0; -} - - -static PyStatus -config_read_env_vars(PyConfig *config) -{ - PyStatus status; - int use_env = config->use_environment; - - /* Get environment variables */ - _Py_get_env_flag(use_env, &config->parser_debug, "PYTHONDEBUG"); - _Py_get_env_flag(use_env, &config->verbose, "PYTHONVERBOSE"); - _Py_get_env_flag(use_env, &config->optimization_level, "PYTHONOPTIMIZE"); - _Py_get_env_flag(use_env, &config->inspect, "PYTHONINSPECT"); - - int dont_write_bytecode = 0; - _Py_get_env_flag(use_env, &dont_write_bytecode, "PYTHONDONTWRITEBYTECODE"); - if (dont_write_bytecode) { - config->write_bytecode = 0; - } - - int no_user_site_directory = 0; - _Py_get_env_flag(use_env, &no_user_site_directory, "PYTHONNOUSERSITE"); - if (no_user_site_directory) { - config->user_site_directory = 0; - } - - int unbuffered_stdio = 0; - _Py_get_env_flag(use_env, &unbuffered_stdio, "PYTHONUNBUFFERED"); - if (unbuffered_stdio) { - config->buffered_stdio = 0; - } - -#ifdef MS_WINDOWS - _Py_get_env_flag(use_env, &config->legacy_windows_stdio, - "PYTHONLEGACYWINDOWSSTDIO"); -#endif - - if (config_get_env(config, "PYTHONDUMPREFS")) { - config->dump_refs = 1; - } - if (config_get_env(config, "PYTHONMALLOCSTATS")) { - config->malloc_stats = 1; - } - - if (config->pythonpath_env == NULL) { - status = CONFIG_GET_ENV_DUP(config, &config->pythonpath_env, - L"PYTHONPATH", "PYTHONPATH"); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - } - - if(config->platlibdir == NULL) { - status = CONFIG_GET_ENV_DUP(config, &config->platlibdir, - L"PYTHONPLATLIBDIR", "PYTHONPLATLIBDIR"); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - } - - if (config->use_hash_seed < 0) { - status = config_init_hash_seed(config); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - } - - return _PyStatus_OK(); -} - - -static PyStatus -config_init_tracemalloc(PyConfig *config) -{ - int nframe; - int valid; - - const char *env = config_get_env(config, "PYTHONTRACEMALLOC"); - if (env) { - if (!_Py_str_to_int(env, &nframe)) { - valid = (nframe >= 0); - } - else { - valid = 0; - } - if (!valid) { - return _PyStatus_ERR("PYTHONTRACEMALLOC: invalid number of frames"); - } - config->tracemalloc = nframe; - } - - const wchar_t *xoption = config_get_xoption(config, L"tracemalloc"); - if (xoption) { - const wchar_t *sep = wcschr(xoption, L'='); - if (sep) { - if (!config_wstr_to_int(sep + 1, &nframe)) { - valid = (nframe >= 0); - } - else { - valid = 0; - } - if (!valid) { - return _PyStatus_ERR("-X tracemalloc=NFRAME: " - "invalid number of frames"); - } - } - else { - /* -X tracemalloc behaves as -X tracemalloc=1 */ - nframe = 1; - } - config->tracemalloc = nframe; - } - return _PyStatus_OK(); -} - - -static PyStatus -config_init_pycache_prefix(PyConfig *config) -{ - assert(config->pycache_prefix == NULL); - - const wchar_t *xoption = config_get_xoption(config, L"pycache_prefix"); - if (xoption) { - const wchar_t *sep = wcschr(xoption, L'='); - if (sep && wcslen(sep) > 1) { - config->pycache_prefix = _PyMem_RawWcsdup(sep + 1); - if (config->pycache_prefix == NULL) { - return _PyStatus_NO_MEMORY(); - } - } - else { - // PYTHONPYCACHEPREFIX env var ignored - // if "-X pycache_prefix=" option is used - config->pycache_prefix = NULL; - } - return _PyStatus_OK(); - } - - return CONFIG_GET_ENV_DUP(config, &config->pycache_prefix, - L"PYTHONPYCACHEPREFIX", - "PYTHONPYCACHEPREFIX"); -} - - -static PyStatus -config_read_complex_options(PyConfig *config) -{ - /* More complex options configured by env var and -X option */ - if (config->faulthandler < 0) { - if (config_get_env(config, "PYTHONFAULTHANDLER") - || config_get_xoption(config, L"faulthandler")) { - config->faulthandler = 1; - } - } - if (config_get_env(config, "PYTHONPROFILEIMPORTTIME") - || config_get_xoption(config, L"importtime")) { - config->import_time = 1; - } - - PyStatus status; - if (config->tracemalloc < 0) { - status = config_init_tracemalloc(config); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - } - - if (config->pycache_prefix == NULL) { - status = config_init_pycache_prefix(config); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - } - return _PyStatus_OK(); -} - - -static const wchar_t * -config_get_stdio_errors(const PyPreConfig *preconfig) -{ - if (preconfig->utf8_mode) { - /* UTF-8 Mode uses UTF-8/surrogateescape */ - return L"surrogateescape"; - } - -#ifndef MS_WINDOWS - const char *loc = setlocale(LC_CTYPE, NULL); - if (loc != NULL) { - /* surrogateescape is the default in the legacy C and POSIX locales */ - if (strcmp(loc, "C") == 0 || strcmp(loc, "POSIX") == 0) { - return L"surrogateescape"; - } - -#ifdef PY_COERCE_C_LOCALE - /* surrogateescape is the default in locale coercion target locales */ - if (_Py_IsLocaleCoercionTarget(loc)) { - return L"surrogateescape"; - } -#endif - } - - return L"strict"; -#else - /* On Windows, always use surrogateescape by default */ - return L"surrogateescape"; -#endif -} - - -// See also config_get_fs_encoding() -static PyStatus -config_get_locale_encoding(PyConfig *config, const PyPreConfig *preconfig, - wchar_t **locale_encoding) -{ - wchar_t *encoding = _Py_GetLocaleEncoding(); - if (encoding == NULL) { - return _PyStatus_NO_MEMORY(); - } - PyStatus status = PyConfig_SetString(config, locale_encoding, encoding); - PyMem_RawFree(encoding); - return status; -} - - -static PyStatus -config_init_stdio_encoding(PyConfig *config, - const PyPreConfig *preconfig) -{ - PyStatus status; - - /* If Py_SetStandardStreamEncoding() has been called, use its - arguments if they are not NULL. */ - if (config->stdio_encoding == NULL && _Py_StandardStreamEncoding != NULL) { - status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding, - _Py_StandardStreamEncoding, - "_Py_StandardStreamEncoding"); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - } - - if (config->stdio_errors == NULL && _Py_StandardStreamErrors != NULL) { - status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors, - _Py_StandardStreamErrors, - "_Py_StandardStreamErrors"); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - } - - // Exit if encoding and errors are defined - if (config->stdio_encoding != NULL && config->stdio_errors != NULL) { - return _PyStatus_OK(); - } - - /* PYTHONIOENCODING environment variable */ - const char *opt = config_get_env(config, "PYTHONIOENCODING"); - if (opt) { - char *pythonioencoding = _PyMem_RawStrdup(opt); - if (pythonioencoding == NULL) { - return _PyStatus_NO_MEMORY(); - } - - char *errors = strchr(pythonioencoding, ':'); - if (errors) { - *errors = '\0'; - errors++; - if (!errors[0]) { - errors = NULL; - } - } - - /* Does PYTHONIOENCODING contain an encoding? */ - if (pythonioencoding[0]) { - if (config->stdio_encoding == NULL) { - status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding, - pythonioencoding, - "PYTHONIOENCODING environment variable"); - if (_PyStatus_EXCEPTION(status)) { - PyMem_RawFree(pythonioencoding); - return status; - } - } - - /* If the encoding is set but not the error handler, - use "strict" error handler by default. - PYTHONIOENCODING=latin1 behaves as - PYTHONIOENCODING=latin1:strict. */ - if (!errors) { - errors = "strict"; - } - } - - if (config->stdio_errors == NULL && errors != NULL) { - status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors, - errors, - "PYTHONIOENCODING environment variable"); - if (_PyStatus_EXCEPTION(status)) { - PyMem_RawFree(pythonioencoding); - return status; - } - } - - PyMem_RawFree(pythonioencoding); - } - - /* Choose the default error handler based on the current locale. */ - if (config->stdio_encoding == NULL) { - status = config_get_locale_encoding(config, preconfig, - &config->stdio_encoding); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - } - if (config->stdio_errors == NULL) { - const wchar_t *errors = config_get_stdio_errors(preconfig); - assert(errors != NULL); - - status = PyConfig_SetString(config, &config->stdio_errors, errors); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - } - - return _PyStatus_OK(); -} - - -// See also config_get_locale_encoding() -static PyStatus -config_get_fs_encoding(PyConfig *config, const PyPreConfig *preconfig, - wchar_t **fs_encoding) -{ -#ifdef _Py_FORCE_UTF8_FS_ENCODING - return PyConfig_SetString(config, fs_encoding, L"utf-8"); -#elif defined(MS_WINDOWS) - const wchar_t *encoding; - if (preconfig->legacy_windows_fs_encoding) { - // Legacy Windows filesystem encoding: mbcs/replace - encoding = L"mbcs"; - } - else { - // Windows defaults to utf-8/surrogatepass (PEP 529) - encoding = L"utf-8"; - } - return PyConfig_SetString(config, fs_encoding, encoding); -#else // !MS_WINDOWS - if (preconfig->utf8_mode) { - return PyConfig_SetString(config, fs_encoding, L"utf-8"); - } - - if (_Py_GetForceASCII()) { - return PyConfig_SetString(config, fs_encoding, L"ascii"); - } - - return config_get_locale_encoding(config, preconfig, fs_encoding); -#endif // !MS_WINDOWS -} - - -static PyStatus -config_init_fs_encoding(PyConfig *config, const PyPreConfig *preconfig) -{ - PyStatus status; - - if (config->filesystem_encoding == NULL) { - status = config_get_fs_encoding(config, preconfig, - &config->filesystem_encoding); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - } - - if (config->filesystem_errors == NULL) { - const wchar_t *errors; -#ifdef MS_WINDOWS - if (preconfig->legacy_windows_fs_encoding) { - errors = L"replace"; - } - else { - errors = L"surrogatepass"; - } -#else - errors = L"surrogateescape"; -#endif - status = PyConfig_SetString(config, &config->filesystem_errors, errors); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - } - return _PyStatus_OK(); -} - - -static PyStatus -config_read(PyConfig *config, int compute_path_config) -{ - PyStatus status; - const PyPreConfig *preconfig = &_PyRuntime.preconfig; - - if (config->use_environment) { - status = config_read_env_vars(config); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - } - - /* -X options */ - if (config_get_xoption(config, L"showrefcount")) { - config->show_ref_count = 1; - } - - status = config_read_complex_options(config); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - if (config->home == NULL) { - status = config_init_home(config); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - } - - if (config->executable == NULL) { - status = config_init_executable(config); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - } - - if(config->platlibdir == NULL) { - status = CONFIG_SET_BYTES_STR(config, &config->platlibdir, PLATLIBDIR, - "PLATLIBDIR macro"); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - } - - if (config->_install_importlib) { - status = _PyConfig_InitPathConfig(config, compute_path_config); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - } - - /* default values */ - if (config->dev_mode) { - if (config->faulthandler < 0) { - config->faulthandler = 1; - } - } - if (config->faulthandler < 0) { - config->faulthandler = 0; - } - if (config->tracemalloc < 0) { - config->tracemalloc = 0; - } - if (config->use_hash_seed < 0) { - config->use_hash_seed = 0; - config->hash_seed = 0; - } - - if (config->filesystem_encoding == NULL || config->filesystem_errors == NULL) { - status = config_init_fs_encoding(config, preconfig); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - } - - status = config_init_stdio_encoding(config, preconfig); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - if (config->argv.length < 1) { - /* Ensure at least one (empty) argument is seen */ - status = PyWideStringList_Append(&config->argv, L""); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - } - - if (config->check_hash_pycs_mode == NULL) { - status = PyConfig_SetString(config, &config->check_hash_pycs_mode, - L"default"); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - } - - if (config->configure_c_stdio < 0) { - config->configure_c_stdio = 1; - } - - // Only parse arguments once. - if (config->parse_argv == 1) { - config->parse_argv = 2; - } - - return _PyStatus_OK(); -} - - -static void -config_init_stdio(const PyConfig *config) -{ -#if defined(MS_WINDOWS) || defined(__CYGWIN__) - /* don't translate newlines (\r\n <=> \n) */ - _setmode(fileno(stdin), O_BINARY); - _setmode(fileno(stdout), O_BINARY); - _setmode(fileno(stderr), O_BINARY); -#endif - - if (!config->buffered_stdio) { -#ifdef HAVE_SETVBUF - setvbuf(stdin, (char *)NULL, _IONBF, BUFSIZ); - setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ); - setvbuf(stderr, (char *)NULL, _IONBF, BUFSIZ); -#else /* !HAVE_SETVBUF */ - setbuf(stdin, (char *)NULL); - setbuf(stdout, (char *)NULL); - setbuf(stderr, (char *)NULL); -#endif /* !HAVE_SETVBUF */ - } - else if (config->interactive) { -#ifdef MS_WINDOWS - /* Doesn't have to have line-buffered -- use unbuffered */ - /* Any set[v]buf(stdin, ...) screws up Tkinter :-( */ - setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ); -#else /* !MS_WINDOWS */ -#ifdef HAVE_SETVBUF - setvbuf(stdin, (char *)NULL, _IOLBF, BUFSIZ); - setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ); -#endif /* HAVE_SETVBUF */ -#endif /* !MS_WINDOWS */ - /* Leave stderr alone - it should be unbuffered anyway. */ - } -} - - -/* Write the configuration: - - - set Py_xxx global configuration variables - - initialize C standard streams (stdin, stdout, stderr) */ -PyStatus -_PyConfig_Write(const PyConfig *config, _PyRuntimeState *runtime) -{ - config_set_global_vars(config); - - if (config->configure_c_stdio) { - config_init_stdio(config); - } - - /* Write the new pre-configuration into _PyRuntime */ - PyPreConfig *preconfig = &runtime->preconfig; - preconfig->isolated = config->isolated; - preconfig->use_environment = config->use_environment; - preconfig->dev_mode = config->dev_mode; - - if (_Py_SetArgcArgv(config->orig_argv.length, - config->orig_argv.items) < 0) - { - return _PyStatus_NO_MEMORY(); - } - return _PyStatus_OK(); -} - - -/* --- PyConfig command line parser -------------------------- */ - -static void -config_usage(int error, const wchar_t* program) -{ - FILE *f = error ? stderr : stdout; - - fprintf(f, usage_line, program); - if (error) - fprintf(f, "Try `python -h' for more information.\n"); - else { - fputs(usage_1, f); - fputs(usage_2, f); - fputs(usage_3, f); - fprintf(f, usage_4, (wint_t)DELIM); - fprintf(f, usage_5, (wint_t)DELIM, PYTHONHOMEHELP); - fputs(usage_6, f); - } -} - - -/* Parse the command line arguments */ -static PyStatus -config_parse_cmdline(PyConfig *config, PyWideStringList *warnoptions, - Py_ssize_t *opt_index) -{ - PyStatus status; - const PyWideStringList *argv = &config->argv; - int print_version = 0; - const wchar_t* program = config->program_name; - - _PyOS_ResetGetOpt(); - do { - int longindex = -1; - int c = _PyOS_GetOpt(argv->length, argv->items, &longindex); - if (c == EOF) { - break; - } - - if (c == 'c') { - if (config->run_command == NULL) { - /* -c is the last option; following arguments - that look like options are left for the - command to interpret. */ - size_t len = wcslen(_PyOS_optarg) + 1 + 1; - wchar_t *command = PyMem_RawMalloc(sizeof(wchar_t) * len); - if (command == NULL) { - return _PyStatus_NO_MEMORY(); - } - memcpy(command, _PyOS_optarg, (len - 2) * sizeof(wchar_t)); - command[len - 2] = '\n'; - command[len - 1] = 0; - config->run_command = command; - } - break; - } - - if (c == 'm') { - /* -m is the last option; following arguments - that look like options are left for the - module to interpret. */ - if (config->run_module == NULL) { - config->run_module = _PyMem_RawWcsdup(_PyOS_optarg); - if (config->run_module == NULL) { - return _PyStatus_NO_MEMORY(); - } - } - break; - } - - switch (c) { - case 0: - // Handle long option. - assert(longindex == 0); // Only one long option now. - if (wcscmp(_PyOS_optarg, L"always") == 0 - || wcscmp(_PyOS_optarg, L"never") == 0 - || wcscmp(_PyOS_optarg, L"default") == 0) - { - status = PyConfig_SetString(config, &config->check_hash_pycs_mode, - _PyOS_optarg); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - } else { - fprintf(stderr, "--check-hash-based-pycs must be one of " - "'default', 'always', or 'never'\n"); - config_usage(1, program); - return _PyStatus_EXIT(2); - } - break; - - case 'b': - config->bytes_warning++; - break; - - case 'd': - config->parser_debug++; - break; - - case 'i': - config->inspect++; - config->interactive++; - break; - - case 'E': - case 'I': - case 'X': - /* option handled by _PyPreCmdline_Read() */ - break; - - /* case 'J': reserved for Jython */ - - case 'O': - config->optimization_level++; - break; - - case 'B': - config->write_bytecode = 0; - break; - - case 's': - config->user_site_directory = 0; - break; - - case 'S': - config->site_import = 0; - break; - - case 't': - /* ignored for backwards compatibility */ - break; - - case 'u': - config->buffered_stdio = 0; - break; - - case 'v': - config->verbose++; - break; - - case 'x': - config->skip_source_first_line = 1; - break; - - case 'h': - case '?': - config_usage(0, program); - return _PyStatus_EXIT(0); - - case 'V': - print_version++; - break; - - case 'W': - status = PyWideStringList_Append(warnoptions, _PyOS_optarg); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - break; - - case 'q': - config->quiet++; - break; - - case 'R': - config->use_hash_seed = 0; - break; - - /* This space reserved for other options */ - - default: - /* unknown argument: parsing failed */ - config_usage(1, program); - return _PyStatus_EXIT(2); - } - } while (1); - - if (print_version) { - printf("Python %s\n", - (print_version >= 2) ? Py_GetVersion() : PY_VERSION); - return _PyStatus_EXIT(0); - } - - if (config->run_command == NULL && config->run_module == NULL - && _PyOS_optind < argv->length - && wcscmp(argv->items[_PyOS_optind], L"-") != 0 - && config->run_filename == NULL) - { - config->run_filename = _PyMem_RawWcsdup(argv->items[_PyOS_optind]); - if (config->run_filename == NULL) { - return _PyStatus_NO_MEMORY(); - } - } - - if (config->run_command != NULL || config->run_module != NULL) { - /* Backup _PyOS_optind */ - _PyOS_optind--; - } - - *opt_index = _PyOS_optind; - - return _PyStatus_OK(); -} - - -#ifdef MS_WINDOWS -# define WCSTOK wcstok_s -#else -# define WCSTOK wcstok -#endif - -/* Get warning options from PYTHONWARNINGS environment variable. */ -static PyStatus -config_init_env_warnoptions(PyConfig *config, PyWideStringList *warnoptions) -{ - PyStatus status; - /* CONFIG_GET_ENV_DUP requires dest to be initialized to NULL */ - wchar_t *env = NULL; - status = CONFIG_GET_ENV_DUP(config, &env, - L"PYTHONWARNINGS", "PYTHONWARNINGS"); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - /* env var is not set or is empty */ - if (env == NULL) { - return _PyStatus_OK(); - } - - - wchar_t *warning, *context = NULL; - for (warning = WCSTOK(env, L",", &context); - warning != NULL; - warning = WCSTOK(NULL, L",", &context)) - { - status = PyWideStringList_Append(warnoptions, warning); - if (_PyStatus_EXCEPTION(status)) { - PyMem_RawFree(env); - return status; - } - } - PyMem_RawFree(env); - return _PyStatus_OK(); -} - - -static PyStatus -warnoptions_append(PyConfig *config, PyWideStringList *options, - const wchar_t *option) -{ - /* config_init_warnoptions() add existing config warnoptions at the end: - ensure that the new option is not already present in this list to - prevent change the options order when config_init_warnoptions() is - called twice. */ - if (_PyWideStringList_Find(&config->warnoptions, option)) { - /* Already present: do nothing */ - return _PyStatus_OK(); - } - if (_PyWideStringList_Find(options, option)) { - /* Already present: do nothing */ - return _PyStatus_OK(); - } - return PyWideStringList_Append(options, option); -} - - -static PyStatus -warnoptions_extend(PyConfig *config, PyWideStringList *options, - const PyWideStringList *options2) -{ - const Py_ssize_t len = options2->length; - wchar_t *const *items = options2->items; - - for (Py_ssize_t i = 0; i < len; i++) { - PyStatus status = warnoptions_append(config, options, items[i]); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - } - return _PyStatus_OK(); -} - - -static PyStatus -config_init_warnoptions(PyConfig *config, - const PyWideStringList *cmdline_warnoptions, - const PyWideStringList *env_warnoptions, - const PyWideStringList *sys_warnoptions) -{ - PyStatus status; - PyWideStringList options = _PyWideStringList_INIT; - - /* Priority of warnings options, lowest to highest: - * - * - any implicit filters added by _warnings.c/warnings.py - * - PyConfig.dev_mode: "default" filter - * - PYTHONWARNINGS environment variable - * - '-W' command line options - * - PyConfig.bytes_warning ('-b' and '-bb' command line options): - * "default::BytesWarning" or "error::BytesWarning" filter - * - early PySys_AddWarnOption() calls - * - PyConfig.warnoptions - * - * PyConfig.warnoptions is copied to sys.warnoptions. Since the warnings - * module works on the basis of "the most recently added filter will be - * checked first", we add the lowest precedence entries first so that later - * entries override them. - */ - - if (config->dev_mode) { - status = warnoptions_append(config, &options, L"default"); - if (_PyStatus_EXCEPTION(status)) { - goto error; - } - } - - status = warnoptions_extend(config, &options, env_warnoptions); - if (_PyStatus_EXCEPTION(status)) { - goto error; - } - - status = warnoptions_extend(config, &options, cmdline_warnoptions); - if (_PyStatus_EXCEPTION(status)) { - goto error; - } - - /* If the bytes_warning_flag isn't set, bytesobject.c and bytearrayobject.c - * don't even try to emit a warning, so we skip setting the filter in that - * case. - */ - if (config->bytes_warning) { - const wchar_t *filter; - if (config->bytes_warning> 1) { - filter = L"error::BytesWarning"; - } - else { - filter = L"default::BytesWarning"; - } - status = warnoptions_append(config, &options, filter); - if (_PyStatus_EXCEPTION(status)) { - goto error; - } - } - - status = warnoptions_extend(config, &options, sys_warnoptions); - if (_PyStatus_EXCEPTION(status)) { - goto error; - } - - /* Always add all PyConfig.warnoptions options */ - status = _PyWideStringList_Extend(&options, &config->warnoptions); - if (_PyStatus_EXCEPTION(status)) { - goto error; - } - - _PyWideStringList_Clear(&config->warnoptions); - config->warnoptions = options; - return _PyStatus_OK(); - -error: - _PyWideStringList_Clear(&options); - return status; -} - - -static PyStatus -config_update_argv(PyConfig *config, Py_ssize_t opt_index) -{ - const PyWideStringList *cmdline_argv = &config->argv; - PyWideStringList config_argv = _PyWideStringList_INIT; - - /* Copy argv to be able to modify it (to force -c/-m) */ - if (cmdline_argv->length <= opt_index) { - /* Ensure at least one (empty) argument is seen */ - PyStatus status = PyWideStringList_Append(&config_argv, L""); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - } - else { - PyWideStringList slice; - slice.length = cmdline_argv->length - opt_index; - slice.items = &cmdline_argv->items[opt_index]; - if (_PyWideStringList_Copy(&config_argv, &slice) < 0) { - return _PyStatus_NO_MEMORY(); - } - } - assert(config_argv.length >= 1); - - wchar_t *arg0 = NULL; - if (config->run_command != NULL) { - /* Force sys.argv[0] = '-c' */ - arg0 = L"-c"; - } - else if (config->run_module != NULL) { - /* Force sys.argv[0] = '-m'*/ - arg0 = L"-m"; - } - - if (arg0 != NULL) { - arg0 = _PyMem_RawWcsdup(arg0); - if (arg0 == NULL) { - _PyWideStringList_Clear(&config_argv); - return _PyStatus_NO_MEMORY(); - } - - PyMem_RawFree(config_argv.items[0]); - config_argv.items[0] = arg0; - } - - _PyWideStringList_Clear(&config->argv); - config->argv = config_argv; - return _PyStatus_OK(); -} - - -static PyStatus -core_read_precmdline(PyConfig *config, _PyPreCmdline *precmdline) -{ - PyStatus status; - - if (config->parse_argv == 1) { - if (_PyWideStringList_Copy(&precmdline->argv, &config->argv) < 0) { - return _PyStatus_NO_MEMORY(); - } - } - - PyPreConfig preconfig; - - status = _PyPreConfig_InitFromPreConfig(&preconfig, &_PyRuntime.preconfig); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - _PyPreConfig_GetConfig(&preconfig, config); - - status = _PyPreCmdline_Read(precmdline, &preconfig); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - status = _PyPreCmdline_SetConfig(precmdline, config); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - return _PyStatus_OK(); -} - - -/* Get run_filename absolute path */ -static PyStatus -config_run_filename_abspath(PyConfig *config) -{ - if (!config->run_filename) { - return _PyStatus_OK(); - } - -#ifndef MS_WINDOWS - if (_Py_isabs(config->run_filename)) { - /* path is already absolute */ - return _PyStatus_OK(); - } -#endif - - wchar_t *abs_filename; - if (_Py_abspath(config->run_filename, &abs_filename) < 0) { - /* failed to get the absolute path of the command line filename: - ignore the error, keep the relative path */ - return _PyStatus_OK(); - } - if (abs_filename == NULL) { - return _PyStatus_NO_MEMORY(); - } - - PyMem_RawFree(config->run_filename); - config->run_filename = abs_filename; - return _PyStatus_OK(); -} - - -static PyStatus -config_read_cmdline(PyConfig *config) -{ - PyStatus status; - PyWideStringList cmdline_warnoptions = _PyWideStringList_INIT; - PyWideStringList env_warnoptions = _PyWideStringList_INIT; - PyWideStringList sys_warnoptions = _PyWideStringList_INIT; - - if (config->parse_argv < 0) { - config->parse_argv = 1; - } - - if (config->program_name == NULL) { - status = config_init_program_name(config); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - } - - if (config->parse_argv == 1) { - Py_ssize_t opt_index; - status = config_parse_cmdline(config, &cmdline_warnoptions, &opt_index); - if (_PyStatus_EXCEPTION(status)) { - goto done; - } - - status = config_run_filename_abspath(config); - if (_PyStatus_EXCEPTION(status)) { - goto done; - } - - status = config_update_argv(config, opt_index); - if (_PyStatus_EXCEPTION(status)) { - goto done; - } - } - else { - status = config_run_filename_abspath(config); - if (_PyStatus_EXCEPTION(status)) { - goto done; - } - } - - if (config->use_environment) { - status = config_init_env_warnoptions(config, &env_warnoptions); - if (_PyStatus_EXCEPTION(status)) { - goto done; - } - } - - /* Handle early PySys_AddWarnOption() calls */ - status = _PySys_ReadPreinitWarnOptions(&sys_warnoptions); - if (_PyStatus_EXCEPTION(status)) { - goto done; - } - - status = config_init_warnoptions(config, - &cmdline_warnoptions, - &env_warnoptions, - &sys_warnoptions); - if (_PyStatus_EXCEPTION(status)) { - goto done; - } - - status = _PyStatus_OK(); - -done: - _PyWideStringList_Clear(&cmdline_warnoptions); - _PyWideStringList_Clear(&env_warnoptions); - _PyWideStringList_Clear(&sys_warnoptions); - return status; -} - - -PyStatus -_PyConfig_SetPyArgv(PyConfig *config, const _PyArgv *args) -{ - PyStatus status = _Py_PreInitializeFromConfig(config, args); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - return _PyArgv_AsWstrList(args, &config->argv); -} - - -/* Set config.argv: decode argv using Py_DecodeLocale(). Pre-initialize Python - if needed to ensure that encodings are properly configured. */ -PyStatus -PyConfig_SetBytesArgv(PyConfig *config, Py_ssize_t argc, char * const *argv) -{ - _PyArgv args = { - .argc = argc, - .use_bytes_argv = 1, - .bytes_argv = argv, - .wchar_argv = NULL}; - return _PyConfig_SetPyArgv(config, &args); -} - - -PyStatus -PyConfig_SetArgv(PyConfig *config, Py_ssize_t argc, wchar_t * const *argv) -{ - _PyArgv args = { - .argc = argc, - .use_bytes_argv = 0, - .bytes_argv = NULL, - .wchar_argv = argv}; - return _PyConfig_SetPyArgv(config, &args); -} - - -PyStatus -PyConfig_SetWideStringList(PyConfig *config, PyWideStringList *list, - Py_ssize_t length, wchar_t **items) -{ - PyStatus status = _Py_PreInitializeFromConfig(config, NULL); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - PyWideStringList list2 = {.length = length, .items = items}; - if (_PyWideStringList_Copy(list, &list2) < 0) { - return _PyStatus_NO_MEMORY(); - } - return _PyStatus_OK(); -} - - -/* Read the configuration into PyConfig from: - - * Command line arguments - * Environment variables - * Py_xxx global configuration variables - - The only side effects are to modify config and to call _Py_SetArgcArgv(). */ -PyStatus -_PyConfig_Read(PyConfig *config, int compute_path_config) -{ - PyStatus status; - - status = _Py_PreInitializeFromConfig(config, NULL); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - config_get_global_vars(config); - - if (config->orig_argv.length == 0 - && !(config->argv.length == 1 - && wcscmp(config->argv.items[0], L"") == 0)) - { - if (_PyWideStringList_Copy(&config->orig_argv, &config->argv) < 0) { - return _PyStatus_NO_MEMORY(); - } - } - - _PyPreCmdline precmdline = _PyPreCmdline_INIT; - status = core_read_precmdline(config, &precmdline); - if (_PyStatus_EXCEPTION(status)) { - goto done; - } - - assert(config->isolated >= 0); - if (config->isolated) { - config->use_environment = 0; - config->user_site_directory = 0; - } - - status = config_read_cmdline(config); - if (_PyStatus_EXCEPTION(status)) { - goto done; - } - - /* Handle early PySys_AddXOption() calls */ - status = _PySys_ReadPreinitXOptions(config); - if (_PyStatus_EXCEPTION(status)) { - goto done; - } - - status = config_read(config, compute_path_config); - if (_PyStatus_EXCEPTION(status)) { - goto done; - } - - assert(config_check_consistency(config)); - - status = _PyStatus_OK(); - -done: - _PyPreCmdline_Clear(&precmdline); - return status; -} - - -PyStatus -PyConfig_Read(PyConfig *config) -{ - return _PyConfig_Read(config, 1); -} - - -PyObject* -_Py_GetConfigsAsDict(void) -{ - PyObject *result = NULL; - PyObject *dict = NULL; - - result = PyDict_New(); - if (result == NULL) { - goto error; - } - - /* global result */ - dict = _Py_GetGlobalVariablesAsDict(); - if (dict == NULL) { - goto error; - } - if (PyDict_SetItemString(result, "global_config", dict) < 0) { - goto error; - } - Py_CLEAR(dict); - - /* pre config */ - PyInterpreterState *interp = _PyInterpreterState_GET(); - const PyPreConfig *pre_config = &interp->runtime->preconfig; - dict = _PyPreConfig_AsDict(pre_config); - if (dict == NULL) { - goto error; - } - if (PyDict_SetItemString(result, "pre_config", dict) < 0) { - goto error; - } - Py_CLEAR(dict); - - /* core config */ - const PyConfig *config = _PyInterpreterState_GetConfig(interp); - dict = _PyConfig_AsDict(config); - if (dict == NULL) { - goto error; - } - if (PyDict_SetItemString(result, "config", dict) < 0) { - goto error; - } - Py_CLEAR(dict); - - /* path config */ - dict = _PyPathConfig_AsDict(); - if (dict == NULL) { - goto error; - } - if (PyDict_SetItemString(result, "path_config", dict) < 0) { - goto error; - } - Py_CLEAR(dict); - - return result; - -error: - Py_XDECREF(result); - Py_XDECREF(dict); - return NULL; -} - - -static void -init_dump_ascii_wstr(const wchar_t *str) -{ - if (str == NULL) { - PySys_WriteStderr("(not set)"); - return; - } - - PySys_WriteStderr("'"); - for (; *str != L'\0'; str++) { - unsigned int ch = (unsigned int)*str; - if (ch == L'\'') { - PySys_WriteStderr("\\'"); - } else if (0x20 <= ch && ch < 0x7f) { - PySys_WriteStderr("%c", ch); - } - else if (ch <= 0xff) { - PySys_WriteStderr("\\x%02x", ch); - } -#if SIZEOF_WCHAR_T > 2 - else if (ch > 0xffff) { - PySys_WriteStderr("\\U%08x", ch); - } -#endif - else { - PySys_WriteStderr("\\u%04x", ch); - } - } - PySys_WriteStderr("'"); -} - - -/* Dump the Python path configuration into sys.stderr */ -void -_Py_DumpPathConfig(PyThreadState *tstate) -{ - PyObject *exc_type, *exc_value, *exc_tb; - _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb); - - PySys_WriteStderr("Python path configuration:\n"); - -#define DUMP_CONFIG(NAME, FIELD) \ - do { \ - PySys_WriteStderr(" " NAME " = "); \ - init_dump_ascii_wstr(config->FIELD); \ - PySys_WriteStderr("\n"); \ - } while (0) - - const PyConfig *config = _PyInterpreterState_GetConfig(tstate->interp); - DUMP_CONFIG("PYTHONHOME", home); - DUMP_CONFIG("PYTHONPATH", pythonpath_env); - DUMP_CONFIG("program name", program_name); - PySys_WriteStderr(" isolated = %i\n", config->isolated); - PySys_WriteStderr(" environment = %i\n", config->use_environment); - PySys_WriteStderr(" user site = %i\n", config->user_site_directory); - PySys_WriteStderr(" import site = %i\n", config->site_import); -#undef DUMP_CONFIG - -#define DUMP_SYS(NAME) \ - do { \ - obj = PySys_GetObject(#NAME); \ - PySys_FormatStderr(" sys.%s = ", #NAME); \ - if (obj != NULL) { \ - PySys_FormatStderr("%A", obj); \ - } \ - else { \ - PySys_WriteStderr("(not set)"); \ - } \ - PySys_FormatStderr("\n"); \ - } while (0) - - PyObject *obj; - DUMP_SYS(_base_executable); - DUMP_SYS(base_prefix); - DUMP_SYS(base_exec_prefix); - DUMP_SYS(platlibdir); - DUMP_SYS(executable); - DUMP_SYS(prefix); - DUMP_SYS(exec_prefix); -#undef DUMP_SYS - - PyObject *sys_path = PySys_GetObject("path"); /* borrowed reference */ - if (sys_path != NULL && PyList_Check(sys_path)) { - PySys_WriteStderr(" sys.path = [\n"); - Py_ssize_t len = PyList_GET_SIZE(sys_path); - for (Py_ssize_t i=0; i < len; i++) { - PyObject *path = PyList_GET_ITEM(sys_path, i); - PySys_FormatStderr(" %A,\n", path); - } - PySys_WriteStderr(" ]\n"); - } - - _PyErr_Restore(tstate, exc_type, exc_value, exc_tb); -} diff --git a/contrib/tools/python3/src/Python/marshal.c b/contrib/tools/python3/src/Python/marshal.c deleted file mode 100644 index 41252406060..00000000000 --- a/contrib/tools/python3/src/Python/marshal.c +++ /dev/null @@ -1,1824 +0,0 @@ - -/* Write Python objects to files and read them back. - This is primarily intended for writing and reading compiled Python code, - even though dicts, lists, sets and frozensets, not commonly seen in - code objects, are supported. - Version 3 of this protocol properly supports circular links - and sharing. */ - -#define PY_SSIZE_T_CLEAN - -#include "Python.h" -#include "longintrepr.h" -#include "code.h" -#include "marshal.h" -#include "pycore_hashtable.h" - -/*[clinic input] -module marshal -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=c982b7930dee17db]*/ - -#include "clinic/marshal.c.h" - -/* High water mark to determine when the marshalled object is dangerously deep - * and risks coring the interpreter. When the object stack gets this deep, - * raise an exception instead of continuing. - * On Windows debug builds, reduce this value. - * - * BUG: https://bugs.python.org/issue33720 - * On Windows PGO builds, the r_object function overallocates its stack and - * can cause a stack overflow. We reduce the maximum depth for all Windows - * releases to protect against this. - * #if defined(MS_WINDOWS) && defined(_DEBUG) - */ -#if defined(MS_WINDOWS) -#define MAX_MARSHAL_STACK_DEPTH 1000 -#else -#define MAX_MARSHAL_STACK_DEPTH 2000 -#endif - -#define TYPE_NULL '0' -#define TYPE_NONE 'N' -#define TYPE_FALSE 'F' -#define TYPE_TRUE 'T' -#define TYPE_STOPITER 'S' -#define TYPE_ELLIPSIS '.' -#define TYPE_INT 'i' -/* TYPE_INT64 is not generated anymore. - Supported for backward compatibility only. */ -#define TYPE_INT64 'I' -#define TYPE_FLOAT 'f' -#define TYPE_BINARY_FLOAT 'g' -#define TYPE_COMPLEX 'x' -#define TYPE_BINARY_COMPLEX 'y' -#define TYPE_LONG 'l' -#define TYPE_STRING 's' -#define TYPE_INTERNED 't' -#define TYPE_REF 'r' -#define TYPE_TUPLE '(' -#define TYPE_LIST '[' -#define TYPE_DICT '{' -#define TYPE_CODE 'c' -#define TYPE_UNICODE 'u' -#define TYPE_UNKNOWN '?' -#define TYPE_SET '<' -#define TYPE_FROZENSET '>' -#define FLAG_REF '\x80' /* with a type, add obj to index */ - -#define TYPE_ASCII 'a' -#define TYPE_ASCII_INTERNED 'A' -#define TYPE_SMALL_TUPLE ')' -#define TYPE_SHORT_ASCII 'z' -#define TYPE_SHORT_ASCII_INTERNED 'Z' - -#define WFERR_OK 0 -#define WFERR_UNMARSHALLABLE 1 -#define WFERR_NESTEDTOODEEP 2 -#define WFERR_NOMEMORY 3 - -typedef struct { - FILE *fp; - int error; /* see WFERR_* values */ - int depth; - PyObject *str; - char *ptr; - const char *end; - char *buf; - _Py_hashtable_t *hashtable; - int version; -} WFILE; - -#define w_byte(c, p) do { \ - if ((p)->ptr != (p)->end || w_reserve((p), 1)) \ - *(p)->ptr++ = (c); \ - } while(0) - -static void -w_flush(WFILE *p) -{ - assert(p->fp != NULL); - fwrite(p->buf, 1, p->ptr - p->buf, p->fp); - p->ptr = p->buf; -} - -static int -w_reserve(WFILE *p, Py_ssize_t needed) -{ - Py_ssize_t pos, size, delta; - if (p->ptr == NULL) - return 0; /* An error already occurred */ - if (p->fp != NULL) { - w_flush(p); - return needed <= p->end - p->ptr; - } - assert(p->str != NULL); - pos = p->ptr - p->buf; - size = PyBytes_GET_SIZE(p->str); - if (size > 16*1024*1024) - delta = (size >> 3); /* 12.5% overallocation */ - else - delta = size + 1024; - delta = Py_MAX(delta, needed); - if (delta > PY_SSIZE_T_MAX - size) { - p->error = WFERR_NOMEMORY; - return 0; - } - size += delta; - if (_PyBytes_Resize(&p->str, size) != 0) { - p->end = p->ptr = p->buf = NULL; - return 0; - } - else { - p->buf = PyBytes_AS_STRING(p->str); - p->ptr = p->buf + pos; - p->end = p->buf + size; - return 1; - } -} - -static void -w_string(const void *s, Py_ssize_t n, WFILE *p) -{ - Py_ssize_t m; - if (!n || p->ptr == NULL) - return; - m = p->end - p->ptr; - if (p->fp != NULL) { - if (n <= m) { - memcpy(p->ptr, s, n); - p->ptr += n; - } - else { - w_flush(p); - fwrite(s, 1, n, p->fp); - } - } - else { - if (n <= m || w_reserve(p, n - m)) { - memcpy(p->ptr, s, n); - p->ptr += n; - } - } -} - -static void -w_short(int x, WFILE *p) -{ - w_byte((char)( x & 0xff), p); - w_byte((char)((x>> 8) & 0xff), p); -} - -static void -w_long(long x, WFILE *p) -{ - w_byte((char)( x & 0xff), p); - w_byte((char)((x>> 8) & 0xff), p); - w_byte((char)((x>>16) & 0xff), p); - w_byte((char)((x>>24) & 0xff), p); -} - -#define SIZE32_MAX 0x7FFFFFFF - -#if SIZEOF_SIZE_T > 4 -# define W_SIZE(n, p) do { \ - if ((n) > SIZE32_MAX) { \ - (p)->depth--; \ - (p)->error = WFERR_UNMARSHALLABLE; \ - return; \ - } \ - w_long((long)(n), p); \ - } while(0) -#else -# define W_SIZE w_long -#endif - -static void -w_pstring(const void *s, Py_ssize_t n, WFILE *p) -{ - W_SIZE(n, p); - w_string(s, n, p); -} - -static void -w_short_pstring(const void *s, Py_ssize_t n, WFILE *p) -{ - w_byte(Py_SAFE_DOWNCAST(n, Py_ssize_t, unsigned char), p); - w_string(s, n, p); -} - -/* We assume that Python ints are stored internally in base some power of - 2**15; for the sake of portability we'll always read and write them in base - exactly 2**15. */ - -#define PyLong_MARSHAL_SHIFT 15 -#define PyLong_MARSHAL_BASE ((short)1 << PyLong_MARSHAL_SHIFT) -#define PyLong_MARSHAL_MASK (PyLong_MARSHAL_BASE - 1) -#if PyLong_SHIFT % PyLong_MARSHAL_SHIFT != 0 -#error "PyLong_SHIFT must be a multiple of PyLong_MARSHAL_SHIFT" -#endif -#define PyLong_MARSHAL_RATIO (PyLong_SHIFT / PyLong_MARSHAL_SHIFT) - -#define W_TYPE(t, p) do { \ - w_byte((t) | flag, (p)); \ -} while(0) - -static void -w_PyLong(const PyLongObject *ob, char flag, WFILE *p) -{ - Py_ssize_t i, j, n, l; - digit d; - - W_TYPE(TYPE_LONG, p); - if (Py_SIZE(ob) == 0) { - w_long((long)0, p); - return; - } - - /* set l to number of base PyLong_MARSHAL_BASE digits */ - n = Py_ABS(Py_SIZE(ob)); - l = (n-1) * PyLong_MARSHAL_RATIO; - d = ob->ob_digit[n-1]; - assert(d != 0); /* a PyLong is always normalized */ - do { - d >>= PyLong_MARSHAL_SHIFT; - l++; - } while (d != 0); - if (l > SIZE32_MAX) { - p->depth--; - p->error = WFERR_UNMARSHALLABLE; - return; - } - w_long((long)(Py_SIZE(ob) > 0 ? l : -l), p); - - for (i=0; i < n-1; i++) { - d = ob->ob_digit[i]; - for (j=0; j < PyLong_MARSHAL_RATIO; j++) { - w_short(d & PyLong_MARSHAL_MASK, p); - d >>= PyLong_MARSHAL_SHIFT; - } - assert (d == 0); - } - d = ob->ob_digit[n-1]; - do { - w_short(d & PyLong_MARSHAL_MASK, p); - d >>= PyLong_MARSHAL_SHIFT; - } while (d != 0); -} - -static void -w_float_bin(double v, WFILE *p) -{ - unsigned char buf[8]; - if (_PyFloat_Pack8(v, buf, 1) < 0) { - p->error = WFERR_UNMARSHALLABLE; - return; - } - w_string(buf, 8, p); -} - -static void -w_float_str(double v, WFILE *p) -{ - char *buf = PyOS_double_to_string(v, 'g', 17, 0, NULL); - if (!buf) { - p->error = WFERR_NOMEMORY; - return; - } - w_short_pstring(buf, strlen(buf), p); - PyMem_Free(buf); -} - -static int -w_ref(PyObject *v, char *flag, WFILE *p) -{ - _Py_hashtable_entry_t *entry; - int w; - - if (p->version < 3 || p->hashtable == NULL) - return 0; /* not writing object references */ - - /* if it has only one reference, it definitely isn't shared */ - if (Py_REFCNT(v) == 1) - return 0; - - entry = _Py_hashtable_get_entry(p->hashtable, v); - if (entry != NULL) { - /* write the reference index to the stream */ - w = (int)(uintptr_t)entry->value; - /* we don't store "long" indices in the dict */ - assert(0 <= w && w <= 0x7fffffff); - w_byte(TYPE_REF, p); - w_long(w, p); - return 1; - } else { - size_t s = p->hashtable->nentries; - /* we don't support long indices */ - if (s >= 0x7fffffff) { - PyErr_SetString(PyExc_ValueError, "too many objects"); - goto err; - } - w = (int)s; - Py_INCREF(v); - if (_Py_hashtable_set(p->hashtable, v, (void *)(uintptr_t)w) < 0) { - Py_DECREF(v); - goto err; - } - *flag |= FLAG_REF; - return 0; - } -err: - p->error = WFERR_UNMARSHALLABLE; - return 1; -} - -static void -w_complex_object(PyObject *v, char flag, WFILE *p); - -static void -w_object(PyObject *v, WFILE *p) -{ - char flag = '\0'; - - p->depth++; - - if (p->depth > MAX_MARSHAL_STACK_DEPTH) { - p->error = WFERR_NESTEDTOODEEP; - } - else if (v == NULL) { - w_byte(TYPE_NULL, p); - } - else if (v == Py_None) { - w_byte(TYPE_NONE, p); - } - else if (v == PyExc_StopIteration) { - w_byte(TYPE_STOPITER, p); - } - else if (v == Py_Ellipsis) { - w_byte(TYPE_ELLIPSIS, p); - } - else if (v == Py_False) { - w_byte(TYPE_FALSE, p); - } - else if (v == Py_True) { - w_byte(TYPE_TRUE, p); - } - else if (!w_ref(v, &flag, p)) - w_complex_object(v, flag, p); - - p->depth--; -} - -static void -w_complex_object(PyObject *v, char flag, WFILE *p) -{ - Py_ssize_t i, n; - - if (PyLong_CheckExact(v)) { - int overflow; - long x = PyLong_AsLongAndOverflow(v, &overflow); - if (overflow) { - w_PyLong((PyLongObject *)v, flag, p); - } - else { -#if SIZEOF_LONG > 4 - long y = Py_ARITHMETIC_RIGHT_SHIFT(long, x, 31); - if (y && y != -1) { - /* Too large for TYPE_INT */ - w_PyLong((PyLongObject*)v, flag, p); - } - else -#endif - { - W_TYPE(TYPE_INT, p); - w_long(x, p); - } - } - } - else if (PyFloat_CheckExact(v)) { - if (p->version > 1) { - W_TYPE(TYPE_BINARY_FLOAT, p); - w_float_bin(PyFloat_AS_DOUBLE(v), p); - } - else { - W_TYPE(TYPE_FLOAT, p); - w_float_str(PyFloat_AS_DOUBLE(v), p); - } - } - else if (PyComplex_CheckExact(v)) { - if (p->version > 1) { - W_TYPE(TYPE_BINARY_COMPLEX, p); - w_float_bin(PyComplex_RealAsDouble(v), p); - w_float_bin(PyComplex_ImagAsDouble(v), p); - } - else { - W_TYPE(TYPE_COMPLEX, p); - w_float_str(PyComplex_RealAsDouble(v), p); - w_float_str(PyComplex_ImagAsDouble(v), p); - } - } - else if (PyBytes_CheckExact(v)) { - W_TYPE(TYPE_STRING, p); - w_pstring(PyBytes_AS_STRING(v), PyBytes_GET_SIZE(v), p); - } - else if (PyUnicode_CheckExact(v)) { - if (p->version >= 4 && PyUnicode_IS_ASCII(v)) { - int is_short = PyUnicode_GET_LENGTH(v) < 256; - if (is_short) { - if (PyUnicode_CHECK_INTERNED(v)) - W_TYPE(TYPE_SHORT_ASCII_INTERNED, p); - else - W_TYPE(TYPE_SHORT_ASCII, p); - w_short_pstring(PyUnicode_1BYTE_DATA(v), - PyUnicode_GET_LENGTH(v), p); - } - else { - if (PyUnicode_CHECK_INTERNED(v)) - W_TYPE(TYPE_ASCII_INTERNED, p); - else - W_TYPE(TYPE_ASCII, p); - w_pstring(PyUnicode_1BYTE_DATA(v), - PyUnicode_GET_LENGTH(v), p); - } - } - else { - PyObject *utf8; - utf8 = PyUnicode_AsEncodedString(v, "utf8", "surrogatepass"); - if (utf8 == NULL) { - p->depth--; - p->error = WFERR_UNMARSHALLABLE; - return; - } - if (p->version >= 3 && PyUnicode_CHECK_INTERNED(v)) - W_TYPE(TYPE_INTERNED, p); - else - W_TYPE(TYPE_UNICODE, p); - w_pstring(PyBytes_AS_STRING(utf8), PyBytes_GET_SIZE(utf8), p); - Py_DECREF(utf8); - } - } - else if (PyTuple_CheckExact(v)) { - n = PyTuple_GET_SIZE(v); - if (p->version >= 4 && n < 256) { - W_TYPE(TYPE_SMALL_TUPLE, p); - w_byte((unsigned char)n, p); - } - else { - W_TYPE(TYPE_TUPLE, p); - W_SIZE(n, p); - } - for (i = 0; i < n; i++) { - w_object(PyTuple_GET_ITEM(v, i), p); - } - } - else if (PyList_CheckExact(v)) { - W_TYPE(TYPE_LIST, p); - n = PyList_GET_SIZE(v); - W_SIZE(n, p); - for (i = 0; i < n; i++) { - w_object(PyList_GET_ITEM(v, i), p); - } - } - else if (PyDict_CheckExact(v)) { - Py_ssize_t pos; - PyObject *key, *value; - W_TYPE(TYPE_DICT, p); - /* This one is NULL object terminated! */ - pos = 0; - while (PyDict_Next(v, &pos, &key, &value)) { - w_object(key, p); - w_object(value, p); - } - w_object((PyObject *)NULL, p); - } - else if (PyAnySet_CheckExact(v)) { - PyObject *value; - Py_ssize_t pos = 0; - Py_hash_t hash; - - if (PyFrozenSet_CheckExact(v)) - W_TYPE(TYPE_FROZENSET, p); - else - W_TYPE(TYPE_SET, p); - n = PySet_GET_SIZE(v); - W_SIZE(n, p); - while (_PySet_NextEntry(v, &pos, &value, &hash)) { - w_object(value, p); - } - } - else if (PyCode_Check(v)) { - PyCodeObject *co = (PyCodeObject *)v; - W_TYPE(TYPE_CODE, p); - w_long(co->co_argcount, p); - w_long(co->co_posonlyargcount, p); - w_long(co->co_kwonlyargcount, p); - w_long(co->co_nlocals, p); - w_long(co->co_stacksize, p); - w_long(co->co_flags, p); - w_object(co->co_code, p); - w_object(co->co_consts, p); - w_object(co->co_names, p); - w_object(co->co_varnames, p); - w_object(co->co_freevars, p); - w_object(co->co_cellvars, p); - w_object(co->co_filename, p); - w_object(co->co_name, p); - w_long(co->co_firstlineno, p); - w_object(co->co_linetable, p); - } - else if (PyObject_CheckBuffer(v)) { - /* Write unknown bytes-like objects as a bytes object */ - Py_buffer view; - if (PyObject_GetBuffer(v, &view, PyBUF_SIMPLE) != 0) { - w_byte(TYPE_UNKNOWN, p); - p->depth--; - p->error = WFERR_UNMARSHALLABLE; - return; - } - W_TYPE(TYPE_STRING, p); - w_pstring(view.buf, view.len, p); - PyBuffer_Release(&view); - } - else { - W_TYPE(TYPE_UNKNOWN, p); - p->error = WFERR_UNMARSHALLABLE; - } -} - -static void -w_decref_entry(void *key) -{ - PyObject *entry_key = (PyObject *)key; - Py_XDECREF(entry_key); -} - -static int -w_init_refs(WFILE *wf, int version) -{ - if (version >= 3) { - wf->hashtable = _Py_hashtable_new_full(_Py_hashtable_hash_ptr, - _Py_hashtable_compare_direct, - w_decref_entry, NULL, NULL); - if (wf->hashtable == NULL) { - PyErr_NoMemory(); - return -1; - } - } - return 0; -} - -static void -w_clear_refs(WFILE *wf) -{ - if (wf->hashtable != NULL) { - _Py_hashtable_destroy(wf->hashtable); - } -} - -/* version currently has no effect for writing ints. */ -void -PyMarshal_WriteLongToFile(long x, FILE *fp, int version) -{ - char buf[4]; - WFILE wf; - memset(&wf, 0, sizeof(wf)); - wf.fp = fp; - wf.ptr = wf.buf = buf; - wf.end = wf.ptr + sizeof(buf); - wf.error = WFERR_OK; - wf.version = version; - w_long(x, &wf); - w_flush(&wf); -} - -void -PyMarshal_WriteObjectToFile(PyObject *x, FILE *fp, int version) -{ - char buf[BUFSIZ]; - WFILE wf; - if (PySys_Audit("marshal.dumps", "Oi", x, version) < 0) { - return; /* caller must check PyErr_Occurred() */ - } - memset(&wf, 0, sizeof(wf)); - wf.fp = fp; - wf.ptr = wf.buf = buf; - wf.end = wf.ptr + sizeof(buf); - wf.error = WFERR_OK; - wf.version = version; - if (w_init_refs(&wf, version)) { - return; /* caller must check PyErr_Occurred() */ - } - w_object(x, &wf); - w_clear_refs(&wf); - w_flush(&wf); -} - -typedef struct { - FILE *fp; - int depth; - PyObject *readable; /* Stream-like object being read from */ - const char *ptr; - const char *end; - char *buf; - Py_ssize_t buf_size; - PyObject *refs; /* a list */ -} RFILE; - -static const char * -r_string(Py_ssize_t n, RFILE *p) -{ - Py_ssize_t read = -1; - - if (p->ptr != NULL) { - /* Fast path for loads() */ - const char *res = p->ptr; - Py_ssize_t left = p->end - p->ptr; - if (left < n) { - PyErr_SetString(PyExc_EOFError, - "marshal data too short"); - return NULL; - } - p->ptr += n; - return res; - } - if (p->buf == NULL) { - p->buf = PyMem_Malloc(n); - if (p->buf == NULL) { - PyErr_NoMemory(); - return NULL; - } - p->buf_size = n; - } - else if (p->buf_size < n) { - char *tmp = PyMem_Realloc(p->buf, n); - if (tmp == NULL) { - PyErr_NoMemory(); - return NULL; - } - p->buf = tmp; - p->buf_size = n; - } - - if (!p->readable) { - assert(p->fp != NULL); - read = fread(p->buf, 1, n, p->fp); - } - else { - _Py_IDENTIFIER(readinto); - PyObject *res, *mview; - Py_buffer buf; - - if (PyBuffer_FillInfo(&buf, NULL, p->buf, n, 0, PyBUF_CONTIG) == -1) - return NULL; - mview = PyMemoryView_FromBuffer(&buf); - if (mview == NULL) - return NULL; - - res = _PyObject_CallMethodId(p->readable, &PyId_readinto, "N", mview); - if (res != NULL) { - read = PyNumber_AsSsize_t(res, PyExc_ValueError); - Py_DECREF(res); - } - } - if (read != n) { - if (!PyErr_Occurred()) { - if (read > n) - PyErr_Format(PyExc_ValueError, - "read() returned too much data: " - "%zd bytes requested, %zd returned", - n, read); - else - PyErr_SetString(PyExc_EOFError, - "EOF read where not expected"); - } - return NULL; - } - return p->buf; -} - -static int -r_byte(RFILE *p) -{ - int c = EOF; - - if (p->ptr != NULL) { - if (p->ptr < p->end) - c = (unsigned char) *p->ptr++; - return c; - } - if (!p->readable) { - assert(p->fp); - c = getc(p->fp); - } - else { - const char *ptr = r_string(1, p); - if (ptr != NULL) - c = *(const unsigned char *) ptr; - } - return c; -} - -static int -r_short(RFILE *p) -{ - short x = -1; - const unsigned char *buffer; - - buffer = (const unsigned char *) r_string(2, p); - if (buffer != NULL) { - x = buffer[0]; - x |= buffer[1] << 8; - /* Sign-extension, in case short greater than 16 bits */ - x |= -(x & 0x8000); - } - return x; -} - -static long -r_long(RFILE *p) -{ - long x = -1; - const unsigned char *buffer; - - buffer = (const unsigned char *) r_string(4, p); - if (buffer != NULL) { - x = buffer[0]; - x |= (long)buffer[1] << 8; - x |= (long)buffer[2] << 16; - x |= (long)buffer[3] << 24; -#if SIZEOF_LONG > 4 - /* Sign extension for 64-bit machines */ - x |= -(x & 0x80000000L); -#endif - } - return x; -} - -/* r_long64 deals with the TYPE_INT64 code. */ -static PyObject * -r_long64(RFILE *p) -{ - const unsigned char *buffer = (const unsigned char *) r_string(8, p); - if (buffer == NULL) { - return NULL; - } - return _PyLong_FromByteArray(buffer, 8, - 1 /* little endian */, - 1 /* signed */); -} - -static PyObject * -r_PyLong(RFILE *p) -{ - PyLongObject *ob; - long n, size, i; - int j, md, shorts_in_top_digit; - digit d; - - n = r_long(p); - if (PyErr_Occurred()) - return NULL; - if (n == 0) - return (PyObject *)_PyLong_New(0); - if (n < -SIZE32_MAX || n > SIZE32_MAX) { - PyErr_SetString(PyExc_ValueError, - "bad marshal data (long size out of range)"); - return NULL; - } - - size = 1 + (Py_ABS(n) - 1) / PyLong_MARSHAL_RATIO; - shorts_in_top_digit = 1 + (Py_ABS(n) - 1) % PyLong_MARSHAL_RATIO; - ob = _PyLong_New(size); - if (ob == NULL) - return NULL; - - Py_SET_SIZE(ob, n > 0 ? size : -size); - - for (i = 0; i < size-1; i++) { - d = 0; - for (j=0; j < PyLong_MARSHAL_RATIO; j++) { - md = r_short(p); - if (PyErr_Occurred()) { - Py_DECREF(ob); - return NULL; - } - if (md < 0 || md > PyLong_MARSHAL_BASE) - goto bad_digit; - d += (digit)md << j*PyLong_MARSHAL_SHIFT; - } - ob->ob_digit[i] = d; - } - - d = 0; - for (j=0; j < shorts_in_top_digit; j++) { - md = r_short(p); - if (PyErr_Occurred()) { - Py_DECREF(ob); - return NULL; - } - if (md < 0 || md > PyLong_MARSHAL_BASE) - goto bad_digit; - /* topmost marshal digit should be nonzero */ - if (md == 0 && j == shorts_in_top_digit - 1) { - Py_DECREF(ob); - PyErr_SetString(PyExc_ValueError, - "bad marshal data (unnormalized long data)"); - return NULL; - } - d += (digit)md << j*PyLong_MARSHAL_SHIFT; - } - if (PyErr_Occurred()) { - Py_DECREF(ob); - return NULL; - } - /* top digit should be nonzero, else the resulting PyLong won't be - normalized */ - ob->ob_digit[size-1] = d; - return (PyObject *)ob; - bad_digit: - Py_DECREF(ob); - PyErr_SetString(PyExc_ValueError, - "bad marshal data (digit out of range in long)"); - return NULL; -} - -static double -r_float_bin(RFILE *p) -{ - const unsigned char *buf = (const unsigned char *) r_string(8, p); - if (buf == NULL) - return -1; - return _PyFloat_Unpack8(buf, 1); -} - -/* Issue #33720: Disable inlining for reducing the C stack consumption - on PGO builds. */ -_Py_NO_INLINE static double -r_float_str(RFILE *p) -{ - int n; - char buf[256]; - const char *ptr; - n = r_byte(p); - if (n == EOF) { - PyErr_SetString(PyExc_EOFError, - "EOF read where object expected"); - return -1; - } - ptr = r_string(n, p); - if (ptr == NULL) { - return -1; - } - memcpy(buf, ptr, n); - buf[n] = '\0'; - return PyOS_string_to_double(buf, NULL, NULL); -} - -/* allocate the reflist index for a new object. Return -1 on failure */ -static Py_ssize_t -r_ref_reserve(int flag, RFILE *p) -{ - if (flag) { /* currently only FLAG_REF is defined */ - Py_ssize_t idx = PyList_GET_SIZE(p->refs); - if (idx >= 0x7ffffffe) { - PyErr_SetString(PyExc_ValueError, "bad marshal data (index list too large)"); - return -1; - } - if (PyList_Append(p->refs, Py_None) < 0) - return -1; - return idx; - } else - return 0; -} - -/* insert the new object 'o' to the reflist at previously - * allocated index 'idx'. - * 'o' can be NULL, in which case nothing is done. - * if 'o' was non-NULL, and the function succeeds, 'o' is returned. - * if 'o' was non-NULL, and the function fails, 'o' is released and - * NULL returned. This simplifies error checking at the call site since - * a single test for NULL for the function result is enough. - */ -static PyObject * -r_ref_insert(PyObject *o, Py_ssize_t idx, int flag, RFILE *p) -{ - if (o != NULL && flag) { /* currently only FLAG_REF is defined */ - PyObject *tmp = PyList_GET_ITEM(p->refs, idx); - Py_INCREF(o); - PyList_SET_ITEM(p->refs, idx, o); - Py_DECREF(tmp); - } - return o; -} - -/* combination of both above, used when an object can be - * created whenever it is seen in the file, as opposed to - * after having loaded its sub-objects. - */ -static PyObject * -r_ref(PyObject *o, int flag, RFILE *p) -{ - assert(flag & FLAG_REF); - if (o == NULL) - return NULL; - if (PyList_Append(p->refs, o) < 0) { - Py_DECREF(o); /* release the new object */ - return NULL; - } - return o; -} - -static PyObject * -r_object(RFILE *p) -{ - /* NULL is a valid return value, it does not necessarily means that - an exception is set. */ - PyObject *v, *v2; - Py_ssize_t idx = 0; - long i, n; - int type, code = r_byte(p); - int flag, is_interned = 0; - PyObject *retval = NULL; - - if (code == EOF) { - PyErr_SetString(PyExc_EOFError, - "EOF read where object expected"); - return NULL; - } - - p->depth++; - - if (p->depth > MAX_MARSHAL_STACK_DEPTH) { - p->depth--; - PyErr_SetString(PyExc_ValueError, "recursion limit exceeded"); - return NULL; - } - - flag = code & FLAG_REF; - type = code & ~FLAG_REF; - -#define R_REF(O) do{\ - if (flag) \ - O = r_ref(O, flag, p);\ -} while (0) - - switch (type) { - - case TYPE_NULL: - break; - - case TYPE_NONE: - Py_INCREF(Py_None); - retval = Py_None; - break; - - case TYPE_STOPITER: - Py_INCREF(PyExc_StopIteration); - retval = PyExc_StopIteration; - break; - - case TYPE_ELLIPSIS: - Py_INCREF(Py_Ellipsis); - retval = Py_Ellipsis; - break; - - case TYPE_FALSE: - Py_INCREF(Py_False); - retval = Py_False; - break; - - case TYPE_TRUE: - Py_INCREF(Py_True); - retval = Py_True; - break; - - case TYPE_INT: - n = r_long(p); - retval = PyErr_Occurred() ? NULL : PyLong_FromLong(n); - R_REF(retval); - break; - - case TYPE_INT64: - retval = r_long64(p); - R_REF(retval); - break; - - case TYPE_LONG: - retval = r_PyLong(p); - R_REF(retval); - break; - - case TYPE_FLOAT: - { - double x = r_float_str(p); - if (x == -1.0 && PyErr_Occurred()) - break; - retval = PyFloat_FromDouble(x); - R_REF(retval); - break; - } - - case TYPE_BINARY_FLOAT: - { - double x = r_float_bin(p); - if (x == -1.0 && PyErr_Occurred()) - break; - retval = PyFloat_FromDouble(x); - R_REF(retval); - break; - } - - case TYPE_COMPLEX: - { - Py_complex c; - c.real = r_float_str(p); - if (c.real == -1.0 && PyErr_Occurred()) - break; - c.imag = r_float_str(p); - if (c.imag == -1.0 && PyErr_Occurred()) - break; - retval = PyComplex_FromCComplex(c); - R_REF(retval); - break; - } - - case TYPE_BINARY_COMPLEX: - { - Py_complex c; - c.real = r_float_bin(p); - if (c.real == -1.0 && PyErr_Occurred()) - break; - c.imag = r_float_bin(p); - if (c.imag == -1.0 && PyErr_Occurred()) - break; - retval = PyComplex_FromCComplex(c); - R_REF(retval); - break; - } - - case TYPE_STRING: - { - const char *ptr; - n = r_long(p); - if (PyErr_Occurred()) - break; - if (n < 0 || n > SIZE32_MAX) { - PyErr_SetString(PyExc_ValueError, "bad marshal data (bytes object size out of range)"); - break; - } - v = PyBytes_FromStringAndSize((char *)NULL, n); - if (v == NULL) - break; - ptr = r_string(n, p); - if (ptr == NULL) { - Py_DECREF(v); - break; - } - memcpy(PyBytes_AS_STRING(v), ptr, n); - retval = v; - R_REF(retval); - break; - } - - case TYPE_ASCII_INTERNED: - is_interned = 1; - /* fall through */ - case TYPE_ASCII: - n = r_long(p); - if (PyErr_Occurred()) - break; - if (n < 0 || n > SIZE32_MAX) { - PyErr_SetString(PyExc_ValueError, "bad marshal data (string size out of range)"); - break; - } - goto _read_ascii; - - case TYPE_SHORT_ASCII_INTERNED: - is_interned = 1; - /* fall through */ - case TYPE_SHORT_ASCII: - n = r_byte(p); - if (n == EOF) { - PyErr_SetString(PyExc_EOFError, - "EOF read where object expected"); - break; - } - _read_ascii: - { - const char *ptr; - ptr = r_string(n, p); - if (ptr == NULL) - break; - v = PyUnicode_FromKindAndData(PyUnicode_1BYTE_KIND, ptr, n); - if (v == NULL) - break; - if (is_interned) - PyUnicode_InternInPlace(&v); - retval = v; - R_REF(retval); - break; - } - - case TYPE_INTERNED: - is_interned = 1; - /* fall through */ - case TYPE_UNICODE: - { - const char *buffer; - - n = r_long(p); - if (PyErr_Occurred()) - break; - if (n < 0 || n > SIZE32_MAX) { - PyErr_SetString(PyExc_ValueError, "bad marshal data (string size out of range)"); - break; - } - if (n != 0) { - buffer = r_string(n, p); - if (buffer == NULL) - break; - v = PyUnicode_DecodeUTF8(buffer, n, "surrogatepass"); - } - else { - v = PyUnicode_New(0, 0); - } - if (v == NULL) - break; - if (is_interned) - PyUnicode_InternInPlace(&v); - retval = v; - R_REF(retval); - break; - } - - case TYPE_SMALL_TUPLE: - n = (unsigned char) r_byte(p); - if (PyErr_Occurred()) - break; - goto _read_tuple; - case TYPE_TUPLE: - n = r_long(p); - if (PyErr_Occurred()) - break; - if (n < 0 || n > SIZE32_MAX) { - PyErr_SetString(PyExc_ValueError, "bad marshal data (tuple size out of range)"); - break; - } - _read_tuple: - v = PyTuple_New(n); - R_REF(v); - if (v == NULL) - break; - - for (i = 0; i < n; i++) { - v2 = r_object(p); - if ( v2 == NULL ) { - if (!PyErr_Occurred()) - PyErr_SetString(PyExc_TypeError, - "NULL object in marshal data for tuple"); - Py_DECREF(v); - v = NULL; - break; - } - PyTuple_SET_ITEM(v, i, v2); - } - retval = v; - break; - - case TYPE_LIST: - n = r_long(p); - if (PyErr_Occurred()) - break; - if (n < 0 || n > SIZE32_MAX) { - PyErr_SetString(PyExc_ValueError, "bad marshal data (list size out of range)"); - break; - } - v = PyList_New(n); - R_REF(v); - if (v == NULL) - break; - for (i = 0; i < n; i++) { - v2 = r_object(p); - if ( v2 == NULL ) { - if (!PyErr_Occurred()) - PyErr_SetString(PyExc_TypeError, - "NULL object in marshal data for list"); - Py_DECREF(v); - v = NULL; - break; - } - PyList_SET_ITEM(v, i, v2); - } - retval = v; - break; - - case TYPE_DICT: - v = PyDict_New(); - R_REF(v); - if (v == NULL) - break; - for (;;) { - PyObject *key, *val; - key = r_object(p); - if (key == NULL) - break; - val = r_object(p); - if (val == NULL) { - Py_DECREF(key); - break; - } - if (PyDict_SetItem(v, key, val) < 0) { - Py_DECREF(key); - Py_DECREF(val); - break; - } - Py_DECREF(key); - Py_DECREF(val); - } - if (PyErr_Occurred()) { - Py_DECREF(v); - v = NULL; - } - retval = v; - break; - - case TYPE_SET: - case TYPE_FROZENSET: - n = r_long(p); - if (PyErr_Occurred()) - break; - if (n < 0 || n > SIZE32_MAX) { - PyErr_SetString(PyExc_ValueError, "bad marshal data (set size out of range)"); - break; - } - - if (n == 0 && type == TYPE_FROZENSET) { - /* call frozenset() to get the empty frozenset singleton */ - v = _PyObject_CallNoArg((PyObject*)&PyFrozenSet_Type); - if (v == NULL) - break; - R_REF(v); - retval = v; - } - else { - v = (type == TYPE_SET) ? PySet_New(NULL) : PyFrozenSet_New(NULL); - if (type == TYPE_SET) { - R_REF(v); - } else { - /* must use delayed registration of frozensets because they must - * be init with a refcount of 1 - */ - idx = r_ref_reserve(flag, p); - if (idx < 0) - Py_CLEAR(v); /* signal error */ - } - if (v == NULL) - break; - - for (i = 0; i < n; i++) { - v2 = r_object(p); - if ( v2 == NULL ) { - if (!PyErr_Occurred()) - PyErr_SetString(PyExc_TypeError, - "NULL object in marshal data for set"); - Py_DECREF(v); - v = NULL; - break; - } - if (PySet_Add(v, v2) == -1) { - Py_DECREF(v); - Py_DECREF(v2); - v = NULL; - break; - } - Py_DECREF(v2); - } - if (type != TYPE_SET) - v = r_ref_insert(v, idx, flag, p); - retval = v; - } - break; - - case TYPE_CODE: - { - int argcount; - int posonlyargcount; - int kwonlyargcount; - int nlocals; - int stacksize; - int flags; - PyObject *code = NULL; - PyObject *consts = NULL; - PyObject *names = NULL; - PyObject *varnames = NULL; - PyObject *freevars = NULL; - PyObject *cellvars = NULL; - PyObject *filename = NULL; - PyObject *name = NULL; - int firstlineno; - PyObject *linetable = NULL; - - idx = r_ref_reserve(flag, p); - if (idx < 0) - break; - - v = NULL; - - /* XXX ignore long->int overflows for now */ - argcount = (int)r_long(p); - if (PyErr_Occurred()) - goto code_error; - posonlyargcount = (int)r_long(p); - if (PyErr_Occurred()) { - goto code_error; - } - kwonlyargcount = (int)r_long(p); - if (PyErr_Occurred()) - goto code_error; - nlocals = (int)r_long(p); - if (PyErr_Occurred()) - goto code_error; - stacksize = (int)r_long(p); - if (PyErr_Occurred()) - goto code_error; - flags = (int)r_long(p); - if (PyErr_Occurred()) - goto code_error; - code = r_object(p); - if (code == NULL) - goto code_error; - consts = r_object(p); - if (consts == NULL) - goto code_error; - names = r_object(p); - if (names == NULL) - goto code_error; - varnames = r_object(p); - if (varnames == NULL) - goto code_error; - freevars = r_object(p); - if (freevars == NULL) - goto code_error; - cellvars = r_object(p); - if (cellvars == NULL) - goto code_error; - filename = r_object(p); - if (filename == NULL) - goto code_error; - name = r_object(p); - if (name == NULL) - goto code_error; - firstlineno = (int)r_long(p); - if (firstlineno == -1 && PyErr_Occurred()) - break; - linetable = r_object(p); - if (linetable == NULL) - goto code_error; - - v = (PyObject *) PyCode_NewWithPosOnlyArgs( - argcount, posonlyargcount, kwonlyargcount, - nlocals, stacksize, flags, - code, consts, names, varnames, - freevars, cellvars, filename, name, - firstlineno, linetable); - v = r_ref_insert(v, idx, flag, p); - - code_error: - Py_XDECREF(code); - Py_XDECREF(consts); - Py_XDECREF(names); - Py_XDECREF(varnames); - Py_XDECREF(freevars); - Py_XDECREF(cellvars); - Py_XDECREF(filename); - Py_XDECREF(name); - Py_XDECREF(linetable); - } - retval = v; - break; - - case TYPE_REF: - n = r_long(p); - if (n < 0 || n >= PyList_GET_SIZE(p->refs)) { - if (n == -1 && PyErr_Occurred()) - break; - PyErr_SetString(PyExc_ValueError, "bad marshal data (invalid reference)"); - break; - } - v = PyList_GET_ITEM(p->refs, n); - if (v == Py_None) { - PyErr_SetString(PyExc_ValueError, "bad marshal data (invalid reference)"); - break; - } - Py_INCREF(v); - retval = v; - break; - - default: - /* Bogus data got written, which isn't ideal. - This will let you keep working and recover. */ - PyErr_SetString(PyExc_ValueError, "bad marshal data (unknown type code)"); - break; - - } - p->depth--; - return retval; -} - -static PyObject * -read_object(RFILE *p) -{ - PyObject *v; - if (PyErr_Occurred()) { - fprintf(stderr, "XXX readobject called with exception set\n"); - return NULL; - } - if (p->ptr && p->end) { - if (PySys_Audit("marshal.loads", "y#", p->ptr, (Py_ssize_t)(p->end - p->ptr)) < 0) { - return NULL; - } - } else if (p->fp || p->readable) { - if (PySys_Audit("marshal.load", NULL) < 0) { - return NULL; - } - } - v = r_object(p); - if (v == NULL && !PyErr_Occurred()) - PyErr_SetString(PyExc_TypeError, "NULL object in marshal data for object"); - return v; -} - -int -PyMarshal_ReadShortFromFile(FILE *fp) -{ - RFILE rf; - int res; - assert(fp); - rf.readable = NULL; - rf.fp = fp; - rf.end = rf.ptr = NULL; - rf.buf = NULL; - res = r_short(&rf); - if (rf.buf != NULL) - PyMem_Free(rf.buf); - return res; -} - -long -PyMarshal_ReadLongFromFile(FILE *fp) -{ - RFILE rf; - long res; - rf.fp = fp; - rf.readable = NULL; - rf.ptr = rf.end = NULL; - rf.buf = NULL; - res = r_long(&rf); - if (rf.buf != NULL) - PyMem_Free(rf.buf); - return res; -} - -/* Return size of file in bytes; < 0 if unknown or INT_MAX if too big */ -static off_t -getfilesize(FILE *fp) -{ - struct _Py_stat_struct st; - if (_Py_fstat_noraise(fileno(fp), &st) != 0) - return -1; -#if SIZEOF_OFF_T == 4 - else if (st.st_size >= INT_MAX) - return (off_t)INT_MAX; -#endif - else - return (off_t)st.st_size; -} - -/* If we can get the size of the file up-front, and it's reasonably small, - * read it in one gulp and delegate to ...FromString() instead. Much quicker - * than reading a byte at a time from file; speeds .pyc imports. - * CAUTION: since this may read the entire remainder of the file, don't - * call it unless you know you're done with the file. - */ -PyObject * -PyMarshal_ReadLastObjectFromFile(FILE *fp) -{ -/* REASONABLE_FILE_LIMIT is by defn something big enough for Tkinter.pyc. */ -#define REASONABLE_FILE_LIMIT (1L << 18) - off_t filesize; - filesize = getfilesize(fp); - if (filesize > 0 && filesize <= REASONABLE_FILE_LIMIT) { - char* pBuf = (char *)PyMem_Malloc(filesize); - if (pBuf != NULL) { - size_t n = fread(pBuf, 1, (size_t)filesize, fp); - PyObject* v = PyMarshal_ReadObjectFromString(pBuf, n); - PyMem_Free(pBuf); - return v; - } - - } - /* We don't have fstat, or we do but the file is larger than - * REASONABLE_FILE_LIMIT or malloc failed -- read a byte at a time. - */ - return PyMarshal_ReadObjectFromFile(fp); - -#undef REASONABLE_FILE_LIMIT -} - -PyObject * -PyMarshal_ReadObjectFromFile(FILE *fp) -{ - RFILE rf; - PyObject *result; - rf.fp = fp; - rf.readable = NULL; - rf.depth = 0; - rf.ptr = rf.end = NULL; - rf.buf = NULL; - rf.refs = PyList_New(0); - if (rf.refs == NULL) - return NULL; - result = read_object(&rf); - Py_DECREF(rf.refs); - if (rf.buf != NULL) - PyMem_Free(rf.buf); - return result; -} - -PyObject * -PyMarshal_ReadObjectFromString(const char *str, Py_ssize_t len) -{ - RFILE rf; - PyObject *result; - rf.fp = NULL; - rf.readable = NULL; - rf.ptr = str; - rf.end = str + len; - rf.buf = NULL; - rf.depth = 0; - rf.refs = PyList_New(0); - if (rf.refs == NULL) - return NULL; - result = read_object(&rf); - Py_DECREF(rf.refs); - if (rf.buf != NULL) - PyMem_Free(rf.buf); - return result; -} - -PyObject * -PyMarshal_WriteObjectToString(PyObject *x, int version) -{ - WFILE wf; - - if (PySys_Audit("marshal.dumps", "Oi", x, version) < 0) { - return NULL; - } - memset(&wf, 0, sizeof(wf)); - wf.str = PyBytes_FromStringAndSize((char *)NULL, 50); - if (wf.str == NULL) - return NULL; - wf.ptr = wf.buf = PyBytes_AS_STRING(wf.str); - wf.end = wf.ptr + PyBytes_GET_SIZE(wf.str); - wf.error = WFERR_OK; - wf.version = version; - if (w_init_refs(&wf, version)) { - Py_DECREF(wf.str); - return NULL; - } - w_object(x, &wf); - w_clear_refs(&wf); - if (wf.str != NULL) { - const char *base = PyBytes_AS_STRING(wf.str); - if (_PyBytes_Resize(&wf.str, (Py_ssize_t)(wf.ptr - base)) < 0) - return NULL; - } - if (wf.error != WFERR_OK) { - Py_XDECREF(wf.str); - if (wf.error == WFERR_NOMEMORY) - PyErr_NoMemory(); - else - PyErr_SetString(PyExc_ValueError, - (wf.error==WFERR_UNMARSHALLABLE)?"unmarshallable object" - :"object too deeply nested to marshal"); - return NULL; - } - return wf.str; -} - -/* And an interface for Python programs... */ -/*[clinic input] -marshal.dump - - value: object - Must be a supported type. - file: object - Must be a writeable binary file. - version: int(c_default="Py_MARSHAL_VERSION") = version - Indicates the data format that dump should use. - / - -Write the value on the open file. - -If the value has (or contains an object that has) an unsupported type, a -ValueError exception is raised - but garbage data will also be written -to the file. The object will not be properly read back by load(). -[clinic start generated code]*/ - -static PyObject * -marshal_dump_impl(PyObject *module, PyObject *value, PyObject *file, - int version) -/*[clinic end generated code: output=aaee62c7028a7cb2 input=6c7a3c23c6fef556]*/ -{ - /* XXX Quick hack -- need to do this differently */ - PyObject *s; - PyObject *res; - _Py_IDENTIFIER(write); - - s = PyMarshal_WriteObjectToString(value, version); - if (s == NULL) - return NULL; - res = _PyObject_CallMethodIdOneArg(file, &PyId_write, s); - Py_DECREF(s); - return res; -} - -/*[clinic input] -marshal.load - - file: object - Must be readable binary file. - / - -Read one value from the open file and return it. - -If no valid value is read (e.g. because the data has a different Python -version's incompatible marshal format), raise EOFError, ValueError or -TypeError. - -Note: If an object containing an unsupported type was marshalled with -dump(), load() will substitute None for the unmarshallable type. -[clinic start generated code]*/ - -static PyObject * -marshal_load(PyObject *module, PyObject *file) -/*[clinic end generated code: output=f8e5c33233566344 input=c85c2b594cd8124a]*/ -{ - PyObject *data, *result; - _Py_IDENTIFIER(read); - RFILE rf; - - /* - * Make a call to the read method, but read zero bytes. - * This is to ensure that the object passed in at least - * has a read method which returns bytes. - * This can be removed if we guarantee good error handling - * for r_string() - */ - data = _PyObject_CallMethodId(file, &PyId_read, "i", 0); - if (data == NULL) - return NULL; - if (!PyBytes_Check(data)) { - PyErr_Format(PyExc_TypeError, - "file.read() returned not bytes but %.100s", - Py_TYPE(data)->tp_name); - result = NULL; - } - else { - rf.depth = 0; - rf.fp = NULL; - rf.readable = file; - rf.ptr = rf.end = NULL; - rf.buf = NULL; - if ((rf.refs = PyList_New(0)) != NULL) { - result = read_object(&rf); - Py_DECREF(rf.refs); - if (rf.buf != NULL) - PyMem_Free(rf.buf); - } else - result = NULL; - } - Py_DECREF(data); - return result; -} - -/*[clinic input] -marshal.dumps - - value: object - Must be a supported type. - version: int(c_default="Py_MARSHAL_VERSION") = version - Indicates the data format that dumps should use. - / - -Return the bytes object that would be written to a file by dump(value, file). - -Raise a ValueError exception if value has (or contains an object that has) an -unsupported type. -[clinic start generated code]*/ - -static PyObject * -marshal_dumps_impl(PyObject *module, PyObject *value, int version) -/*[clinic end generated code: output=9c200f98d7256cad input=a2139ea8608e9b27]*/ -{ - return PyMarshal_WriteObjectToString(value, version); -} - -/*[clinic input] -marshal.loads - - bytes: Py_buffer - / - -Convert the bytes-like object to a value. - -If no valid value is found, raise EOFError, ValueError or TypeError. Extra -bytes in the input are ignored. -[clinic start generated code]*/ - -static PyObject * -marshal_loads_impl(PyObject *module, Py_buffer *bytes) -/*[clinic end generated code: output=9fc65985c93d1bb1 input=6f426518459c8495]*/ -{ - RFILE rf; - char *s = bytes->buf; - Py_ssize_t n = bytes->len; - PyObject* result; - rf.fp = NULL; - rf.readable = NULL; - rf.ptr = s; - rf.end = s + n; - rf.depth = 0; - if ((rf.refs = PyList_New(0)) == NULL) - return NULL; - result = read_object(&rf); - Py_DECREF(rf.refs); - return result; -} - -static PyMethodDef marshal_methods[] = { - MARSHAL_DUMP_METHODDEF - MARSHAL_LOAD_METHODDEF - MARSHAL_DUMPS_METHODDEF - MARSHAL_LOADS_METHODDEF - {NULL, NULL} /* sentinel */ -}; - - -PyDoc_STRVAR(module_doc, -"This module contains functions that can read and write Python values in\n\ -a binary format. The format is specific to Python, but independent of\n\ -machine architecture issues.\n\ -\n\ -Not all Python object types are supported; in general, only objects\n\ -whose value is independent from a particular invocation of Python can be\n\ -written and read by this module. The following types are supported:\n\ -None, integers, floating point numbers, strings, bytes, bytearrays,\n\ -tuples, lists, sets, dictionaries, and code objects, where it\n\ -should be understood that tuples, lists and dictionaries are only\n\ -supported as long as the values contained therein are themselves\n\ -supported; and recursive lists and dictionaries should not be written\n\ -(they will cause infinite loops).\n\ -\n\ -Variables:\n\ -\n\ -version -- indicates the format that the module uses. Version 0 is the\n\ - historical format, version 1 shares interned strings and version 2\n\ - uses a binary format for floating point numbers.\n\ - Version 3 shares common object references (New in version 3.4).\n\ -\n\ -Functions:\n\ -\n\ -dump() -- write value to a file\n\ -load() -- read value from a file\n\ -dumps() -- marshal value as a bytes object\n\ -loads() -- read value from a bytes-like object"); - - -static int -marshal_module_exec(PyObject *mod) -{ - if (PyModule_AddIntConstant(mod, "version", Py_MARSHAL_VERSION) < 0) { - return -1; - } - return 0; -} - -static PyModuleDef_Slot marshalmodule_slots[] = { - {Py_mod_exec, marshal_module_exec}, - {0, NULL} -}; - -static struct PyModuleDef marshalmodule = { - PyModuleDef_HEAD_INIT, - .m_name = "marshal", - .m_doc = module_doc, - .m_methods = marshal_methods, - .m_slots = marshalmodule_slots, -}; - -PyMODINIT_FUNC -PyMarshal_Init(void) -{ - return PyModuleDef_Init(&marshalmodule); -} diff --git a/contrib/tools/python3/src/Python/modsupport.c b/contrib/tools/python3/src/Python/modsupport.c deleted file mode 100644 index 8655daa1fc5..00000000000 --- a/contrib/tools/python3/src/Python/modsupport.c +++ /dev/null @@ -1,714 +0,0 @@ - -/* Module support implementation */ - -#include "Python.h" -#include "pycore_abstract.h" // _PyIndex_Check() - -#define FLAG_SIZE_T 1 -typedef double va_double; - -static PyObject *va_build_value(const char *, va_list, int); -static PyObject **va_build_stack(PyObject **small_stack, Py_ssize_t small_stack_len, const char *, va_list, int, Py_ssize_t*); - -/* Package context -- the full module name for package imports */ -const char *_Py_PackageContext = NULL; - - -int -_Py_convert_optional_to_ssize_t(PyObject *obj, void *result) -{ - Py_ssize_t limit; - if (obj == Py_None) { - return 1; - } - else if (_PyIndex_Check(obj)) { - limit = PyNumber_AsSsize_t(obj, PyExc_OverflowError); - if (limit == -1 && PyErr_Occurred()) { - return 0; - } - } - else { - PyErr_Format(PyExc_TypeError, - "argument should be integer or None, not '%.200s'", - Py_TYPE(obj)->tp_name); - return 0; - } - *((Py_ssize_t *)result) = limit; - return 1; -} - - -/* Helper for mkvalue() to scan the length of a format */ - -static Py_ssize_t -countformat(const char *format, char endchar) -{ - Py_ssize_t count = 0; - int level = 0; - while (level > 0 || *format != endchar) { - switch (*format) { - case '\0': - /* Premature end */ - PyErr_SetString(PyExc_SystemError, - "unmatched paren in format"); - return -1; - case '(': - case '[': - case '{': - if (level == 0) { - count++; - } - level++; - break; - case ')': - case ']': - case '}': - level--; - break; - case '#': - case '&': - case ',': - case ':': - case ' ': - case '\t': - break; - default: - if (level == 0) { - count++; - } - } - format++; - } - return count; -} - - -/* Generic function to create a value -- the inverse of getargs() */ -/* After an original idea and first implementation by Steven Miale */ - -static PyObject *do_mktuple(const char**, va_list *, char, Py_ssize_t, int); -static int do_mkstack(PyObject **, const char**, va_list *, char, Py_ssize_t, int); -static PyObject *do_mklist(const char**, va_list *, char, Py_ssize_t, int); -static PyObject *do_mkdict(const char**, va_list *, char, Py_ssize_t, int); -static PyObject *do_mkvalue(const char**, va_list *, int); - - -static void -do_ignore(const char **p_format, va_list *p_va, char endchar, Py_ssize_t n, int flags) -{ - PyObject *v; - Py_ssize_t i; - assert(PyErr_Occurred()); - v = PyTuple_New(n); - for (i = 0; i < n; i++) { - PyObject *exception, *value, *tb, *w; - - PyErr_Fetch(&exception, &value, &tb); - w = do_mkvalue(p_format, p_va, flags); - PyErr_Restore(exception, value, tb); - if (w != NULL) { - if (v != NULL) { - PyTuple_SET_ITEM(v, i, w); - } - else { - Py_DECREF(w); - } - } - } - Py_XDECREF(v); - if (**p_format != endchar) { - PyErr_SetString(PyExc_SystemError, - "Unmatched paren in format"); - return; - } - if (endchar) { - ++*p_format; - } -} - -static PyObject * -do_mkdict(const char **p_format, va_list *p_va, char endchar, Py_ssize_t n, int flags) -{ - PyObject *d; - Py_ssize_t i; - if (n < 0) - return NULL; - if (n % 2) { - PyErr_SetString(PyExc_SystemError, - "Bad dict format"); - do_ignore(p_format, p_va, endchar, n, flags); - return NULL; - } - /* Note that we can't bail immediately on error as this will leak - refcounts on any 'N' arguments. */ - if ((d = PyDict_New()) == NULL) { - do_ignore(p_format, p_va, endchar, n, flags); - return NULL; - } - for (i = 0; i < n; i+= 2) { - PyObject *k, *v; - - k = do_mkvalue(p_format, p_va, flags); - if (k == NULL) { - do_ignore(p_format, p_va, endchar, n - i - 1, flags); - Py_DECREF(d); - return NULL; - } - v = do_mkvalue(p_format, p_va, flags); - if (v == NULL || PyDict_SetItem(d, k, v) < 0) { - do_ignore(p_format, p_va, endchar, n - i - 2, flags); - Py_DECREF(k); - Py_XDECREF(v); - Py_DECREF(d); - return NULL; - } - Py_DECREF(k); - Py_DECREF(v); - } - if (**p_format != endchar) { - Py_DECREF(d); - PyErr_SetString(PyExc_SystemError, - "Unmatched paren in format"); - return NULL; - } - if (endchar) - ++*p_format; - return d; -} - -static PyObject * -do_mklist(const char **p_format, va_list *p_va, char endchar, Py_ssize_t n, int flags) -{ - PyObject *v; - Py_ssize_t i; - if (n < 0) - return NULL; - /* Note that we can't bail immediately on error as this will leak - refcounts on any 'N' arguments. */ - v = PyList_New(n); - if (v == NULL) { - do_ignore(p_format, p_va, endchar, n, flags); - return NULL; - } - for (i = 0; i < n; i++) { - PyObject *w = do_mkvalue(p_format, p_va, flags); - if (w == NULL) { - do_ignore(p_format, p_va, endchar, n - i - 1, flags); - Py_DECREF(v); - return NULL; - } - PyList_SET_ITEM(v, i, w); - } - if (**p_format != endchar) { - Py_DECREF(v); - PyErr_SetString(PyExc_SystemError, - "Unmatched paren in format"); - return NULL; - } - if (endchar) - ++*p_format; - return v; -} - -static int -do_mkstack(PyObject **stack, const char **p_format, va_list *p_va, - char endchar, Py_ssize_t n, int flags) -{ - Py_ssize_t i; - - if (n < 0) { - return -1; - } - /* Note that we can't bail immediately on error as this will leak - refcounts on any 'N' arguments. */ - for (i = 0; i < n; i++) { - PyObject *w = do_mkvalue(p_format, p_va, flags); - if (w == NULL) { - do_ignore(p_format, p_va, endchar, n - i - 1, flags); - goto error; - } - stack[i] = w; - } - if (**p_format != endchar) { - PyErr_SetString(PyExc_SystemError, - "Unmatched paren in format"); - goto error; - } - if (endchar) { - ++*p_format; - } - return 0; - -error: - n = i; - for (i=0; i < n; i++) { - Py_DECREF(stack[i]); - } - return -1; -} - -static PyObject * -do_mktuple(const char **p_format, va_list *p_va, char endchar, Py_ssize_t n, int flags) -{ - PyObject *v; - Py_ssize_t i; - if (n < 0) - return NULL; - /* Note that we can't bail immediately on error as this will leak - refcounts on any 'N' arguments. */ - if ((v = PyTuple_New(n)) == NULL) { - do_ignore(p_format, p_va, endchar, n, flags); - return NULL; - } - for (i = 0; i < n; i++) { - PyObject *w = do_mkvalue(p_format, p_va, flags); - if (w == NULL) { - do_ignore(p_format, p_va, endchar, n - i - 1, flags); - Py_DECREF(v); - return NULL; - } - PyTuple_SET_ITEM(v, i, w); - } - if (**p_format != endchar) { - Py_DECREF(v); - PyErr_SetString(PyExc_SystemError, - "Unmatched paren in format"); - return NULL; - } - if (endchar) - ++*p_format; - return v; -} - -static PyObject * -do_mkvalue(const char **p_format, va_list *p_va, int flags) -{ -#define ERROR_NEED_PY_SSIZE_T_CLEAN \ - { \ - PyErr_SetString(PyExc_SystemError, \ - "PY_SSIZE_T_CLEAN macro must be defined for '#' formats"); \ - return NULL; \ - } - - for (;;) { - switch (*(*p_format)++) { - case '(': - return do_mktuple(p_format, p_va, ')', - countformat(*p_format, ')'), flags); - - case '[': - return do_mklist(p_format, p_va, ']', - countformat(*p_format, ']'), flags); - - case '{': - return do_mkdict(p_format, p_va, '}', - countformat(*p_format, '}'), flags); - - case 'b': - case 'B': - case 'h': - case 'i': - return PyLong_FromLong((long)va_arg(*p_va, int)); - - case 'H': - return PyLong_FromLong((long)va_arg(*p_va, unsigned int)); - - case 'I': - { - unsigned int n; - n = va_arg(*p_va, unsigned int); - return PyLong_FromUnsignedLong(n); - } - - case 'n': -#if SIZEOF_SIZE_T!=SIZEOF_LONG - return PyLong_FromSsize_t(va_arg(*p_va, Py_ssize_t)); -#endif - /* Fall through from 'n' to 'l' if Py_ssize_t is long */ - case 'l': - return PyLong_FromLong(va_arg(*p_va, long)); - - case 'k': - { - unsigned long n; - n = va_arg(*p_va, unsigned long); - return PyLong_FromUnsignedLong(n); - } - - case 'L': - return PyLong_FromLongLong((long long)va_arg(*p_va, long long)); - - case 'K': - return PyLong_FromUnsignedLongLong((long long)va_arg(*p_va, unsigned long long)); - - case 'u': - { - PyObject *v; - Py_UNICODE *u = va_arg(*p_va, Py_UNICODE *); - Py_ssize_t n; - if (**p_format == '#') { - ++*p_format; - if (flags & FLAG_SIZE_T) { - n = va_arg(*p_va, Py_ssize_t); - } - else { - n = va_arg(*p_va, int); - ERROR_NEED_PY_SSIZE_T_CLEAN; - } - } - else - n = -1; - if (u == NULL) { - v = Py_None; - Py_INCREF(v); - } - else { - if (n < 0) - n = wcslen(u); - v = PyUnicode_FromWideChar(u, n); - } - return v; - } - case 'f': - case 'd': - return PyFloat_FromDouble( - (double)va_arg(*p_va, va_double)); - - case 'D': - return PyComplex_FromCComplex( - *((Py_complex *)va_arg(*p_va, Py_complex *))); - - case 'c': - { - char p[1]; - p[0] = (char)va_arg(*p_va, int); - return PyBytes_FromStringAndSize(p, 1); - } - case 'C': - { - int i = va_arg(*p_va, int); - return PyUnicode_FromOrdinal(i); - } - - case 's': - case 'z': - case 'U': /* XXX deprecated alias */ - { - PyObject *v; - const char *str = va_arg(*p_va, const char *); - Py_ssize_t n; - if (**p_format == '#') { - ++*p_format; - if (flags & FLAG_SIZE_T) { - n = va_arg(*p_va, Py_ssize_t); - } - else { - n = va_arg(*p_va, int); - ERROR_NEED_PY_SSIZE_T_CLEAN; - } - } - else - n = -1; - if (str == NULL) { - v = Py_None; - Py_INCREF(v); - } - else { - if (n < 0) { - size_t m = strlen(str); - if (m > PY_SSIZE_T_MAX) { - PyErr_SetString(PyExc_OverflowError, - "string too long for Python string"); - return NULL; - } - n = (Py_ssize_t)m; - } - v = PyUnicode_FromStringAndSize(str, n); - } - return v; - } - - case 'y': - { - PyObject *v; - const char *str = va_arg(*p_va, const char *); - Py_ssize_t n; - if (**p_format == '#') { - ++*p_format; - if (flags & FLAG_SIZE_T) { - n = va_arg(*p_va, Py_ssize_t); - } - else { - n = va_arg(*p_va, int); - ERROR_NEED_PY_SSIZE_T_CLEAN; - } - } - else - n = -1; - if (str == NULL) { - v = Py_None; - Py_INCREF(v); - } - else { - if (n < 0) { - size_t m = strlen(str); - if (m > PY_SSIZE_T_MAX) { - PyErr_SetString(PyExc_OverflowError, - "string too long for Python bytes"); - return NULL; - } - n = (Py_ssize_t)m; - } - v = PyBytes_FromStringAndSize(str, n); - } - return v; - } - - case 'N': - case 'S': - case 'O': - if (**p_format == '&') { - typedef PyObject *(*converter)(void *); - converter func = va_arg(*p_va, converter); - void *arg = va_arg(*p_va, void *); - ++*p_format; - return (*func)(arg); - } - else { - PyObject *v; - v = va_arg(*p_va, PyObject *); - if (v != NULL) { - if (*(*p_format - 1) != 'N') - Py_INCREF(v); - } - else if (!PyErr_Occurred()) - /* If a NULL was passed - * because a call that should - * have constructed a value - * failed, that's OK, and we - * pass the error on; but if - * no error occurred it's not - * clear that the caller knew - * what she was doing. */ - PyErr_SetString(PyExc_SystemError, - "NULL object passed to Py_BuildValue"); - return v; - } - - case ':': - case ',': - case ' ': - case '\t': - break; - - default: - PyErr_SetString(PyExc_SystemError, - "bad format char passed to Py_BuildValue"); - return NULL; - - } - } - -#undef ERROR_NEED_PY_SSIZE_T_CLEAN -} - - -PyObject * -Py_BuildValue(const char *format, ...) -{ - va_list va; - PyObject* retval; - va_start(va, format); - retval = va_build_value(format, va, 0); - va_end(va); - return retval; -} - -PyObject * -_Py_BuildValue_SizeT(const char *format, ...) -{ - va_list va; - PyObject* retval; - va_start(va, format); - retval = va_build_value(format, va, FLAG_SIZE_T); - va_end(va); - return retval; -} - -PyObject * -Py_VaBuildValue(const char *format, va_list va) -{ - return va_build_value(format, va, 0); -} - -PyObject * -_Py_VaBuildValue_SizeT(const char *format, va_list va) -{ - return va_build_value(format, va, FLAG_SIZE_T); -} - -static PyObject * -va_build_value(const char *format, va_list va, int flags) -{ - const char *f = format; - Py_ssize_t n = countformat(f, '\0'); - va_list lva; - PyObject *retval; - - if (n < 0) - return NULL; - if (n == 0) { - Py_RETURN_NONE; - } - va_copy(lva, va); - if (n == 1) { - retval = do_mkvalue(&f, &lva, flags); - } else { - retval = do_mktuple(&f, &lva, '\0', n, flags); - } - va_end(lva); - return retval; -} - -PyObject ** -_Py_VaBuildStack(PyObject **small_stack, Py_ssize_t small_stack_len, - const char *format, va_list va, Py_ssize_t *p_nargs) -{ - return va_build_stack(small_stack, small_stack_len, format, va, 0, p_nargs); -} - -PyObject ** -_Py_VaBuildStack_SizeT(PyObject **small_stack, Py_ssize_t small_stack_len, - const char *format, va_list va, Py_ssize_t *p_nargs) -{ - return va_build_stack(small_stack, small_stack_len, format, va, FLAG_SIZE_T, p_nargs); -} - -static PyObject ** -va_build_stack(PyObject **small_stack, Py_ssize_t small_stack_len, - const char *format, va_list va, int flags, Py_ssize_t *p_nargs) -{ - const char *f; - Py_ssize_t n; - va_list lva; - PyObject **stack; - int res; - - n = countformat(format, '\0'); - if (n < 0) { - *p_nargs = 0; - return NULL; - } - - if (n == 0) { - *p_nargs = 0; - return small_stack; - } - - if (n <= small_stack_len) { - stack = small_stack; - } - else { - stack = PyMem_Malloc(n * sizeof(stack[0])); - if (stack == NULL) { - PyErr_NoMemory(); - return NULL; - } - } - - va_copy(lva, va); - f = format; - res = do_mkstack(stack, &f, &lva, '\0', n, flags); - va_end(lva); - - if (res < 0) { - if (stack != small_stack) { - PyMem_Free(stack); - } - return NULL; - } - - *p_nargs = n; - return stack; -} - - -int -PyModule_AddObjectRef(PyObject *mod, const char *name, PyObject *value) -{ - if (!PyModule_Check(mod)) { - PyErr_SetString(PyExc_TypeError, - "PyModule_AddObjectRef() first argument " - "must be a module"); - return -1; - } - if (!value) { - if (!PyErr_Occurred()) { - PyErr_SetString(PyExc_SystemError, - "PyModule_AddObjectRef() must be called " - "with an exception raised if value is NULL"); - } - return -1; - } - - PyObject *dict = PyModule_GetDict(mod); - if (dict == NULL) { - /* Internal error -- modules must have a dict! */ - PyErr_Format(PyExc_SystemError, "module '%s' has no __dict__", - PyModule_GetName(mod)); - return -1; - } - - if (PyDict_SetItemString(dict, name, value)) { - return -1; - } - return 0; -} - - -int -PyModule_AddObject(PyObject *mod, const char *name, PyObject *value) -{ - int res = PyModule_AddObjectRef(mod, name, value); - if (res == 0) { - Py_DECREF(value); - } - return res; -} - -int -PyModule_AddIntConstant(PyObject *m, const char *name, long value) -{ - PyObject *obj = PyLong_FromLong(value); - if (!obj) { - return -1; - } - int res = PyModule_AddObjectRef(m, name, obj); - Py_DECREF(obj); - return res; -} - -int -PyModule_AddStringConstant(PyObject *m, const char *name, const char *value) -{ - PyObject *obj = PyUnicode_FromString(value); - if (!obj) { - return -1; - } - int res = PyModule_AddObjectRef(m, name, obj); - Py_DECREF(obj); - return res; -} - -int -PyModule_AddType(PyObject *module, PyTypeObject *type) -{ - if (PyType_Ready(type) < 0) { - return -1; - } - - const char *name = _PyType_Name(type); - assert(name != NULL); - - return PyModule_AddObjectRef(module, name, (PyObject *)type); -} diff --git a/contrib/tools/python3/src/Python/mysnprintf.c b/contrib/tools/python3/src/Python/mysnprintf.c deleted file mode 100644 index cd69198011e..00000000000 --- a/contrib/tools/python3/src/Python/mysnprintf.c +++ /dev/null @@ -1,79 +0,0 @@ -#include "Python.h" - -/* snprintf() and vsnprintf() wrappers. - - If the platform has vsnprintf, we use it, else we - emulate it in a half-hearted way. Even if the platform has it, we wrap - it because platforms differ in what vsnprintf does in case the buffer - is too small: C99 behavior is to return the number of characters that - would have been written had the buffer not been too small, and to set - the last byte of the buffer to \0. At least MS _vsnprintf returns a - negative value instead, and fills the entire buffer with non-\0 data. - - The wrappers ensure that str[size-1] is always \0 upon return. - - PyOS_snprintf and PyOS_vsnprintf never write more than size bytes - (including the trailing '\0') into str. - - Return value (rv): - - When 0 <= rv < size, the output conversion was unexceptional, and - rv characters were written to str (excluding a trailing \0 byte at - str[rv]). - - When rv >= size, output conversion was truncated, and a buffer of - size rv+1 would have been needed to avoid truncation. str[size-1] - is \0 in this case. - - When rv < 0, "something bad happened". str[size-1] is \0 in this - case too, but the rest of str is unreliable. It could be that - an error in format codes was detected by libc, or on platforms - with a non-C99 vsnprintf simply that the buffer wasn't big enough - to avoid truncation, or on platforms without any vsnprintf that - PyMem_Malloc couldn't obtain space for a temp buffer. - - CAUTION: Unlike C99, str != NULL and size > 0 are required. - Also, size must be smaller than INT_MAX. -*/ - -int -PyOS_snprintf(char *str, size_t size, const char *format, ...) -{ - int rc; - va_list va; - - va_start(va, format); - rc = PyOS_vsnprintf(str, size, format, va); - va_end(va); - return rc; -} - -int -PyOS_vsnprintf(char *str, size_t size, const char *format, va_list va) -{ - assert(str != NULL); - assert(size > 0); - assert(size <= (INT_MAX - 1)); - assert(format != NULL); - - int len; /* # bytes written, excluding \0 */ - /* We take a size_t as input but return an int. Sanity check - * our input so that it won't cause an overflow in the - * vsnprintf return value. */ - if (size > INT_MAX - 1) { - len = -666; - goto Done; - } - -#if defined(_MSC_VER) - len = _vsnprintf(str, size, format, va); -#else - len = vsnprintf(str, size, format, va); -#endif - -Done: - if (size > 0) { - str[size-1] = '\0'; - } - return len; -} diff --git a/contrib/tools/python3/src/Python/mystrtoul.c b/contrib/tools/python3/src/Python/mystrtoul.c deleted file mode 100644 index 19fa57aa144..00000000000 --- a/contrib/tools/python3/src/Python/mystrtoul.c +++ /dev/null @@ -1,291 +0,0 @@ - -#include "Python.h" - -#if defined(__sgi) && !defined(_SGI_MP_SOURCE) -#define _SGI_MP_SOURCE -#endif - -/* strtol and strtoul, renamed to avoid conflicts */ - - -#include <ctype.h> -#ifdef HAVE_ERRNO_H -#include <errno.h> -#endif - -/* Static overflow check values for bases 2 through 36. - * smallmax[base] is the largest unsigned long i such that - * i * base doesn't overflow unsigned long. - */ -static const unsigned long smallmax[] = { - 0, /* bases 0 and 1 are invalid */ - 0, - ULONG_MAX / 2, - ULONG_MAX / 3, - ULONG_MAX / 4, - ULONG_MAX / 5, - ULONG_MAX / 6, - ULONG_MAX / 7, - ULONG_MAX / 8, - ULONG_MAX / 9, - ULONG_MAX / 10, - ULONG_MAX / 11, - ULONG_MAX / 12, - ULONG_MAX / 13, - ULONG_MAX / 14, - ULONG_MAX / 15, - ULONG_MAX / 16, - ULONG_MAX / 17, - ULONG_MAX / 18, - ULONG_MAX / 19, - ULONG_MAX / 20, - ULONG_MAX / 21, - ULONG_MAX / 22, - ULONG_MAX / 23, - ULONG_MAX / 24, - ULONG_MAX / 25, - ULONG_MAX / 26, - ULONG_MAX / 27, - ULONG_MAX / 28, - ULONG_MAX / 29, - ULONG_MAX / 30, - ULONG_MAX / 31, - ULONG_MAX / 32, - ULONG_MAX / 33, - ULONG_MAX / 34, - ULONG_MAX / 35, - ULONG_MAX / 36, -}; - -/* maximum digits that can't ever overflow for bases 2 through 36, - * calculated by [int(math.floor(math.log(2**32, i))) for i in range(2, 37)]. - * Note that this is pessimistic if sizeof(long) > 4. - */ -#if SIZEOF_LONG == 4 -static const int digitlimit[] = { - 0, 0, 32, 20, 16, 13, 12, 11, 10, 10, /* 0 - 9 */ - 9, 9, 8, 8, 8, 8, 8, 7, 7, 7, /* 10 - 19 */ - 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, /* 20 - 29 */ - 6, 6, 6, 6, 6, 6, 6}; /* 30 - 36 */ -#elif SIZEOF_LONG == 8 -/* [int(math.floor(math.log(2**64, i))) for i in range(2, 37)] */ -static const int digitlimit[] = { - 0, 0, 64, 40, 32, 27, 24, 22, 21, 20, /* 0 - 9 */ - 19, 18, 17, 17, 16, 16, 16, 15, 15, 15, /* 10 - 19 */ - 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, /* 20 - 29 */ - 13, 12, 12, 12, 12, 12, 12}; /* 30 - 36 */ -#else -#error "Need table for SIZEOF_LONG" -#endif - -/* -** strtoul -** This is a general purpose routine for converting -** an ascii string to an integer in an arbitrary base. -** Leading white space is ignored. If 'base' is zero -** it looks for a leading 0b, 0o or 0x to tell which -** base. If these are absent it defaults to 10. -** Base must be 0 or between 2 and 36 (inclusive). -** If 'ptr' is non-NULL it will contain a pointer to -** the end of the scan. -** Errors due to bad pointers will probably result in -** exceptions - we don't check for them. -*/ -unsigned long -PyOS_strtoul(const char *str, char **ptr, int base) -{ - unsigned long result = 0; /* return value of the function */ - int c; /* current input character */ - int ovlimit; /* required digits to overflow */ - - /* skip leading white space */ - while (*str && Py_ISSPACE(*str)) - ++str; - - /* check for leading 0b, 0o or 0x for auto-base or base 16 */ - switch (base) { - case 0: /* look for leading 0b, 0o or 0x */ - if (*str == '0') { - ++str; - if (*str == 'x' || *str == 'X') { - /* there must be at least one digit after 0x */ - if (_PyLong_DigitValue[Py_CHARMASK(str[1])] >= 16) { - if (ptr) - *ptr = (char *)str; - return 0; - } - ++str; - base = 16; - } else if (*str == 'o' || *str == 'O') { - /* there must be at least one digit after 0o */ - if (_PyLong_DigitValue[Py_CHARMASK(str[1])] >= 8) { - if (ptr) - *ptr = (char *)str; - return 0; - } - ++str; - base = 8; - } else if (*str == 'b' || *str == 'B') { - /* there must be at least one digit after 0b */ - if (_PyLong_DigitValue[Py_CHARMASK(str[1])] >= 2) { - if (ptr) - *ptr = (char *)str; - return 0; - } - ++str; - base = 2; - } else { - /* skip all zeroes... */ - while (*str == '0') - ++str; - while (Py_ISSPACE(*str)) - ++str; - if (ptr) - *ptr = (char *)str; - return 0; - } - } - else - base = 10; - break; - - /* even with explicit base, skip leading 0? prefix */ - case 16: - if (*str == '0') { - ++str; - if (*str == 'x' || *str == 'X') { - /* there must be at least one digit after 0x */ - if (_PyLong_DigitValue[Py_CHARMASK(str[1])] >= 16) { - if (ptr) - *ptr = (char *)str; - return 0; - } - ++str; - } - } - break; - case 8: - if (*str == '0') { - ++str; - if (*str == 'o' || *str == 'O') { - /* there must be at least one digit after 0o */ - if (_PyLong_DigitValue[Py_CHARMASK(str[1])] >= 8) { - if (ptr) - *ptr = (char *)str; - return 0; - } - ++str; - } - } - break; - case 2: - if(*str == '0') { - ++str; - if (*str == 'b' || *str == 'B') { - /* there must be at least one digit after 0b */ - if (_PyLong_DigitValue[Py_CHARMASK(str[1])] >= 2) { - if (ptr) - *ptr = (char *)str; - return 0; - } - ++str; - } - } - break; - } - - /* catch silly bases */ - if (base < 2 || base > 36) { - if (ptr) - *ptr = (char *)str; - return 0; - } - - /* skip leading zeroes */ - while (*str == '0') - ++str; - - /* base is guaranteed to be in [2, 36] at this point */ - ovlimit = digitlimit[base]; - - /* do the conversion until non-digit character encountered */ - while ((c = _PyLong_DigitValue[Py_CHARMASK(*str)]) < base) { - if (ovlimit > 0) /* no overflow check required */ - result = result * base + c; - else { /* requires overflow check */ - unsigned long temp_result; - - if (ovlimit < 0) /* guaranteed overflow */ - goto overflowed; - - /* there could be an overflow */ - /* check overflow just from shifting */ - if (result > smallmax[base]) - goto overflowed; - - result *= base; - - /* check overflow from the digit's value */ - temp_result = result + c; - if (temp_result < result) - goto overflowed; - - result = temp_result; - } - - ++str; - --ovlimit; - } - - /* set pointer to point to the last character scanned */ - if (ptr) - *ptr = (char *)str; - - return result; - -overflowed: - if (ptr) { - /* spool through remaining digit characters */ - while (_PyLong_DigitValue[Py_CHARMASK(*str)] < base) - ++str; - *ptr = (char *)str; - } - errno = ERANGE; - return (unsigned long)-1; -} - -/* Checking for overflow in PyOS_strtol is a PITA; see comments - * about PY_ABS_LONG_MIN in longobject.c. - */ -#define PY_ABS_LONG_MIN (0-(unsigned long)LONG_MIN) - -long -PyOS_strtol(const char *str, char **ptr, int base) -{ - long result; - unsigned long uresult; - char sign; - - while (*str && Py_ISSPACE(*str)) - str++; - - sign = *str; - if (sign == '+' || sign == '-') - str++; - - uresult = PyOS_strtoul(str, ptr, base); - - if (uresult <= (unsigned long)LONG_MAX) { - result = (long)uresult; - if (sign == '-') - result = -result; - } - else if (sign == '-' && uresult == PY_ABS_LONG_MIN) { - result = LONG_MIN; - } - else { - errno = ERANGE; - result = LONG_MAX; - } - return result; -} diff --git a/contrib/tools/python3/src/Python/opcode_targets.h b/contrib/tools/python3/src/Python/opcode_targets.h deleted file mode 100644 index 951f8f8a556..00000000000 --- a/contrib/tools/python3/src/Python/opcode_targets.h +++ /dev/null @@ -1,258 +0,0 @@ -static void *opcode_targets[256] = { - &&_unknown_opcode, - &&TARGET_POP_TOP, - &&TARGET_ROT_TWO, - &&TARGET_ROT_THREE, - &&TARGET_DUP_TOP, - &&TARGET_DUP_TOP_TWO, - &&TARGET_ROT_FOUR, - &&_unknown_opcode, - &&_unknown_opcode, - &&TARGET_NOP, - &&TARGET_UNARY_POSITIVE, - &&TARGET_UNARY_NEGATIVE, - &&TARGET_UNARY_NOT, - &&_unknown_opcode, - &&_unknown_opcode, - &&TARGET_UNARY_INVERT, - &&TARGET_BINARY_MATRIX_MULTIPLY, - &&TARGET_INPLACE_MATRIX_MULTIPLY, - &&_unknown_opcode, - &&TARGET_BINARY_POWER, - &&TARGET_BINARY_MULTIPLY, - &&_unknown_opcode, - &&TARGET_BINARY_MODULO, - &&TARGET_BINARY_ADD, - &&TARGET_BINARY_SUBTRACT, - &&TARGET_BINARY_SUBSCR, - &&TARGET_BINARY_FLOOR_DIVIDE, - &&TARGET_BINARY_TRUE_DIVIDE, - &&TARGET_INPLACE_FLOOR_DIVIDE, - &&TARGET_INPLACE_TRUE_DIVIDE, - &&TARGET_GET_LEN, - &&TARGET_MATCH_MAPPING, - &&TARGET_MATCH_SEQUENCE, - &&TARGET_MATCH_KEYS, - &&TARGET_COPY_DICT_WITHOUT_KEYS, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&TARGET_WITH_EXCEPT_START, - &&TARGET_GET_AITER, - &&TARGET_GET_ANEXT, - &&TARGET_BEFORE_ASYNC_WITH, - &&_unknown_opcode, - &&TARGET_END_ASYNC_FOR, - &&TARGET_INPLACE_ADD, - &&TARGET_INPLACE_SUBTRACT, - &&TARGET_INPLACE_MULTIPLY, - &&_unknown_opcode, - &&TARGET_INPLACE_MODULO, - &&TARGET_STORE_SUBSCR, - &&TARGET_DELETE_SUBSCR, - &&TARGET_BINARY_LSHIFT, - &&TARGET_BINARY_RSHIFT, - &&TARGET_BINARY_AND, - &&TARGET_BINARY_XOR, - &&TARGET_BINARY_OR, - &&TARGET_INPLACE_POWER, - &&TARGET_GET_ITER, - &&TARGET_GET_YIELD_FROM_ITER, - &&TARGET_PRINT_EXPR, - &&TARGET_LOAD_BUILD_CLASS, - &&TARGET_YIELD_FROM, - &&TARGET_GET_AWAITABLE, - &&TARGET_LOAD_ASSERTION_ERROR, - &&TARGET_INPLACE_LSHIFT, - &&TARGET_INPLACE_RSHIFT, - &&TARGET_INPLACE_AND, - &&TARGET_INPLACE_XOR, - &&TARGET_INPLACE_OR, - &&_unknown_opcode, - &&_unknown_opcode, - &&TARGET_LIST_TO_TUPLE, - &&TARGET_RETURN_VALUE, - &&TARGET_IMPORT_STAR, - &&TARGET_SETUP_ANNOTATIONS, - &&TARGET_YIELD_VALUE, - &&TARGET_POP_BLOCK, - &&_unknown_opcode, - &&TARGET_POP_EXCEPT, - &&TARGET_STORE_NAME, - &&TARGET_DELETE_NAME, - &&TARGET_UNPACK_SEQUENCE, - &&TARGET_FOR_ITER, - &&TARGET_UNPACK_EX, - &&TARGET_STORE_ATTR, - &&TARGET_DELETE_ATTR, - &&TARGET_STORE_GLOBAL, - &&TARGET_DELETE_GLOBAL, - &&TARGET_ROT_N, - &&TARGET_LOAD_CONST, - &&TARGET_LOAD_NAME, - &&TARGET_BUILD_TUPLE, - &&TARGET_BUILD_LIST, - &&TARGET_BUILD_SET, - &&TARGET_BUILD_MAP, - &&TARGET_LOAD_ATTR, - &&TARGET_COMPARE_OP, - &&TARGET_IMPORT_NAME, - &&TARGET_IMPORT_FROM, - &&TARGET_JUMP_FORWARD, - &&TARGET_JUMP_IF_FALSE_OR_POP, - &&TARGET_JUMP_IF_TRUE_OR_POP, - &&TARGET_JUMP_ABSOLUTE, - &&TARGET_POP_JUMP_IF_FALSE, - &&TARGET_POP_JUMP_IF_TRUE, - &&TARGET_LOAD_GLOBAL, - &&TARGET_IS_OP, - &&TARGET_CONTAINS_OP, - &&TARGET_RERAISE, - &&_unknown_opcode, - &&TARGET_JUMP_IF_NOT_EXC_MATCH, - &&TARGET_SETUP_FINALLY, - &&_unknown_opcode, - &&TARGET_LOAD_FAST, - &&TARGET_STORE_FAST, - &&TARGET_DELETE_FAST, - &&_unknown_opcode, - &&_unknown_opcode, - &&TARGET_GEN_START, - &&TARGET_RAISE_VARARGS, - &&TARGET_CALL_FUNCTION, - &&TARGET_MAKE_FUNCTION, - &&TARGET_BUILD_SLICE, - &&_unknown_opcode, - &&TARGET_LOAD_CLOSURE, - &&TARGET_LOAD_DEREF, - &&TARGET_STORE_DEREF, - &&TARGET_DELETE_DEREF, - &&_unknown_opcode, - &&_unknown_opcode, - &&TARGET_CALL_FUNCTION_KW, - &&TARGET_CALL_FUNCTION_EX, - &&TARGET_SETUP_WITH, - &&TARGET_EXTENDED_ARG, - &&TARGET_LIST_APPEND, - &&TARGET_SET_ADD, - &&TARGET_MAP_ADD, - &&TARGET_LOAD_CLASSDEREF, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&TARGET_MATCH_CLASS, - &&_unknown_opcode, - &&TARGET_SETUP_ASYNC_WITH, - &&TARGET_FORMAT_VALUE, - &&TARGET_BUILD_CONST_KEY_MAP, - &&TARGET_BUILD_STRING, - &&_unknown_opcode, - &&_unknown_opcode, - &&TARGET_LOAD_METHOD, - &&TARGET_CALL_METHOD, - &&TARGET_LIST_EXTEND, - &&TARGET_SET_UPDATE, - &&TARGET_DICT_MERGE, - &&TARGET_DICT_UPDATE, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode -}; diff --git a/contrib/tools/python3/src/Python/pathconfig.c b/contrib/tools/python3/src/Python/pathconfig.c deleted file mode 100644 index 1017a571f2b..00000000000 --- a/contrib/tools/python3/src/Python/pathconfig.c +++ /dev/null @@ -1,818 +0,0 @@ -/* Path configuration like module_search_path (sys.path) */ - -#include "Python.h" -#include "osdefs.h" // DELIM -#include "pycore_initconfig.h" -#include "pycore_fileutils.h" -#include "pycore_pathconfig.h" -#include "pycore_pymem.h" // _PyMem_SetDefaultAllocator() -#include <wchar.h> -#ifdef MS_WINDOWS -# include <windows.h> // GetFullPathNameW(), MAX_PATH -#endif - -#ifdef __cplusplus -extern "C" { -#endif - - -_PyPathConfig _Py_path_config = _PyPathConfig_INIT; - - -static int -copy_wstr(wchar_t **dst, const wchar_t *src) -{ - assert(*dst == NULL); - if (src != NULL) { - *dst = _PyMem_RawWcsdup(src); - if (*dst == NULL) { - return -1; - } - } - else { - *dst = NULL; - } - return 0; -} - - -static void -pathconfig_clear(_PyPathConfig *config) -{ - /* _PyMem_SetDefaultAllocator() is needed to get a known memory allocator, - since Py_SetPath(), Py_SetPythonHome() and Py_SetProgramName() can be - called before Py_Initialize() which can changes the memory allocator. */ - PyMemAllocatorEx old_alloc; - _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - -#define CLEAR(ATTR) \ - do { \ - PyMem_RawFree(ATTR); \ - ATTR = NULL; \ - } while (0) - - CLEAR(config->program_full_path); - CLEAR(config->prefix); - CLEAR(config->exec_prefix); - CLEAR(config->module_search_path); - CLEAR(config->program_name); - CLEAR(config->home); -#ifdef MS_WINDOWS - CLEAR(config->base_executable); -#endif - -#undef CLEAR - - PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); -} - - -static PyStatus -pathconfig_copy(_PyPathConfig *config, const _PyPathConfig *config2) -{ - pathconfig_clear(config); - -#define COPY_ATTR(ATTR) \ - do { \ - if (copy_wstr(&config->ATTR, config2->ATTR) < 0) { \ - return _PyStatus_NO_MEMORY(); \ - } \ - } while (0) - - COPY_ATTR(program_full_path); - COPY_ATTR(prefix); - COPY_ATTR(exec_prefix); - COPY_ATTR(module_search_path); - COPY_ATTR(program_name); - COPY_ATTR(home); -#ifdef MS_WINDOWS - config->isolated = config2->isolated; - config->site_import = config2->site_import; - COPY_ATTR(base_executable); -#endif - -#undef COPY_ATTR - - return _PyStatus_OK(); -} - - -void -_PyPathConfig_ClearGlobal(void) -{ - PyMemAllocatorEx old_alloc; - _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - - pathconfig_clear(&_Py_path_config); - - PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); -} - - -static wchar_t* -_PyWideStringList_Join(const PyWideStringList *list, wchar_t sep) -{ - size_t len = 1; /* NUL terminator */ - for (Py_ssize_t i=0; i < list->length; i++) { - if (i != 0) { - len++; - } - len += wcslen(list->items[i]); - } - - wchar_t *text = PyMem_RawMalloc(len * sizeof(wchar_t)); - if (text == NULL) { - return NULL; - } - wchar_t *str = text; - for (Py_ssize_t i=0; i < list->length; i++) { - wchar_t *path = list->items[i]; - if (i != 0) { - *str++ = sep; - } - len = wcslen(path); - memcpy(str, path, len * sizeof(wchar_t)); - str += len; - } - *str = L'\0'; - - return text; -} - - -static PyStatus -pathconfig_set_from_config(_PyPathConfig *pathconfig, const PyConfig *config) -{ - PyStatus status; - PyMemAllocatorEx old_alloc; - _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - - if (config->module_search_paths_set) { - PyMem_RawFree(pathconfig->module_search_path); - pathconfig->module_search_path = _PyWideStringList_Join(&config->module_search_paths, DELIM); - if (pathconfig->module_search_path == NULL) { - goto no_memory; - } - } - -#define COPY_CONFIG(PATH_ATTR, CONFIG_ATTR) \ - if (config->CONFIG_ATTR) { \ - PyMem_RawFree(pathconfig->PATH_ATTR); \ - pathconfig->PATH_ATTR = NULL; \ - if (copy_wstr(&pathconfig->PATH_ATTR, config->CONFIG_ATTR) < 0) { \ - goto no_memory; \ - } \ - } - - COPY_CONFIG(program_full_path, executable); - COPY_CONFIG(prefix, prefix); - COPY_CONFIG(exec_prefix, exec_prefix); - COPY_CONFIG(program_name, program_name); - COPY_CONFIG(home, home); -#ifdef MS_WINDOWS - COPY_CONFIG(base_executable, base_executable); -#endif - -#undef COPY_CONFIG - - status = _PyStatus_OK(); - goto done; - -no_memory: - status = _PyStatus_NO_MEMORY(); - -done: - PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - return status; -} - -PyObject * -_PyPathConfig_AsDict(void) -{ - PyObject *dict = PyDict_New(); - if (dict == NULL) { - return NULL; - } - -#define SET_ITEM(KEY, EXPR) \ - do { \ - PyObject *obj = (EXPR); \ - if (obj == NULL) { \ - goto fail; \ - } \ - int res = PyDict_SetItemString(dict, KEY, obj); \ - Py_DECREF(obj); \ - if (res < 0) { \ - goto fail; \ - } \ - } while (0) -#define SET_ITEM_STR(KEY) \ - SET_ITEM(#KEY, \ - (_Py_path_config.KEY \ - ? PyUnicode_FromWideChar(_Py_path_config.KEY, -1) \ - : (Py_INCREF(Py_None), Py_None))) -#define SET_ITEM_INT(KEY) \ - SET_ITEM(#KEY, PyLong_FromLong(_Py_path_config.KEY)) - - SET_ITEM_STR(program_full_path); - SET_ITEM_STR(prefix); - SET_ITEM_STR(exec_prefix); - SET_ITEM_STR(module_search_path); - SET_ITEM_STR(program_name); - SET_ITEM_STR(home); -#ifdef MS_WINDOWS - SET_ITEM_INT(isolated); - SET_ITEM_INT(site_import); - SET_ITEM_STR(base_executable); - - { - wchar_t py3path[MAX_PATH]; - HMODULE hPython3 = GetModuleHandleW(PY3_DLLNAME); - PyObject *obj; - if (hPython3 - && GetModuleFileNameW(hPython3, py3path, Py_ARRAY_LENGTH(py3path))) - { - obj = PyUnicode_FromWideChar(py3path, -1); - if (obj == NULL) { - goto fail; - } - } - else { - obj = Py_None; - Py_INCREF(obj); - } - if (PyDict_SetItemString(dict, "python3_dll", obj) < 0) { - Py_DECREF(obj); - goto fail; - } - Py_DECREF(obj); - } -#endif - -#undef SET_ITEM -#undef SET_ITEM_STR -#undef SET_ITEM_INT - - return dict; - -fail: - Py_DECREF(dict); - return NULL; -} - - -PyStatus -_PyConfig_WritePathConfig(const PyConfig *config) -{ - return pathconfig_set_from_config(&_Py_path_config, config); -} - - -static PyStatus -config_init_module_search_paths(PyConfig *config, _PyPathConfig *pathconfig) -{ - assert(!config->module_search_paths_set); - - _PyWideStringList_Clear(&config->module_search_paths); - - const wchar_t *sys_path = pathconfig->module_search_path; - const wchar_t delim = DELIM; - while (1) { - const wchar_t *p = wcschr(sys_path, delim); - if (p == NULL) { - p = sys_path + wcslen(sys_path); /* End of string */ - } - - size_t path_len = (p - sys_path); - wchar_t *path = PyMem_RawMalloc((path_len + 1) * sizeof(wchar_t)); - if (path == NULL) { - return _PyStatus_NO_MEMORY(); - } - memcpy(path, sys_path, path_len * sizeof(wchar_t)); - path[path_len] = L'\0'; - - PyStatus status = PyWideStringList_Append(&config->module_search_paths, path); - PyMem_RawFree(path); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - if (*p == '\0') { - break; - } - sys_path = p + 1; - } - config->module_search_paths_set = 1; - return _PyStatus_OK(); -} - - -/* Calculate the path configuration: - - - exec_prefix - - module_search_path - - prefix - - program_full_path - - On Windows, more fields are calculated: - - - base_executable - - isolated - - site_import - - On other platforms, isolated and site_import are left unchanged, and - _PyConfig_InitPathConfig() copies executable to base_executable (if it's not - set). - - Priority, highest to lowest: - - - PyConfig - - _Py_path_config: set by Py_SetPath(), Py_SetPythonHome() - and Py_SetProgramName() - - _PyPathConfig_Calculate() -*/ -static PyStatus -pathconfig_init(_PyPathConfig *pathconfig, const PyConfig *config, - int compute_path_config) -{ - PyStatus status; - - PyMemAllocatorEx old_alloc; - _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - - status = pathconfig_copy(pathconfig, &_Py_path_config); - if (_PyStatus_EXCEPTION(status)) { - goto done; - } - - status = pathconfig_set_from_config(pathconfig, config); - if (_PyStatus_EXCEPTION(status)) { - goto done; - } - - if (compute_path_config) { - status = _PyPathConfig_Calculate(pathconfig, config); - } - -done: - PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - return status; -} - - -static PyStatus -config_init_pathconfig(PyConfig *config, int compute_path_config) -{ - _PyPathConfig pathconfig = _PyPathConfig_INIT; - PyStatus status; - - status = pathconfig_init(&pathconfig, config, compute_path_config); - if (_PyStatus_EXCEPTION(status)) { - goto done; - } - - if (!config->module_search_paths_set - && pathconfig.module_search_path != NULL) - { - status = config_init_module_search_paths(config, &pathconfig); - if (_PyStatus_EXCEPTION(status)) { - goto done; - } - } - -#define COPY_ATTR(PATH_ATTR, CONFIG_ATTR) \ - if (config->CONFIG_ATTR == NULL && pathconfig.PATH_ATTR != NULL) { \ - if (copy_wstr(&config->CONFIG_ATTR, pathconfig.PATH_ATTR) < 0) { \ - goto no_memory; \ - } \ - } - -#ifdef MS_WINDOWS - if (config->executable != NULL && config->base_executable == NULL) { - /* If executable is set explicitly in the configuration, - ignore calculated base_executable: _PyConfig_InitPathConfig() - will copy executable to base_executable */ - } - else { - COPY_ATTR(base_executable, base_executable); - } -#endif - - COPY_ATTR(program_full_path, executable); - COPY_ATTR(prefix, prefix); - COPY_ATTR(exec_prefix, exec_prefix); - -#undef COPY_ATTR - -#ifdef MS_WINDOWS - /* If a ._pth file is found: isolated and site_import are overridden */ - if (pathconfig.isolated != -1) { - config->isolated = pathconfig.isolated; - } - if (pathconfig.site_import != -1) { - config->site_import = pathconfig.site_import; - } -#endif - - status = _PyStatus_OK(); - goto done; - -no_memory: - status = _PyStatus_NO_MEMORY(); - -done: - pathconfig_clear(&pathconfig); - return status; -} - - -PyStatus -_PyConfig_InitPathConfig(PyConfig *config, int compute_path_config) -{ - /* Do we need to calculate the path? */ - if (!config->module_search_paths_set - || config->executable == NULL - || config->prefix == NULL - || config->exec_prefix == NULL) - { - PyStatus status = config_init_pathconfig(config, compute_path_config); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - } - - if (config->base_prefix == NULL && config->prefix != NULL) { - if (copy_wstr(&config->base_prefix, config->prefix) < 0) { - return _PyStatus_NO_MEMORY(); - } - } - - if (config->base_exec_prefix == NULL && config->exec_prefix != NULL) { - if (copy_wstr(&config->base_exec_prefix, - config->exec_prefix) < 0) { - return _PyStatus_NO_MEMORY(); - } - } - - if (config->base_executable == NULL && config->executable != NULL) { - if (copy_wstr(&config->base_executable, - config->executable) < 0) { - return _PyStatus_NO_MEMORY(); - } - } - - return _PyStatus_OK(); -} - - -/* External interface */ - -static void _Py_NO_RETURN -path_out_of_memory(const char *func) -{ - _Py_FatalErrorFunc(func, "out of memory"); -} - -void -Py_SetPath(const wchar_t *path) -{ - if (path == NULL) { - pathconfig_clear(&_Py_path_config); - return; - } - - PyMemAllocatorEx old_alloc; - _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - - PyMem_RawFree(_Py_path_config.prefix); - PyMem_RawFree(_Py_path_config.exec_prefix); - PyMem_RawFree(_Py_path_config.module_search_path); - - _Py_path_config.prefix = _PyMem_RawWcsdup(L""); - _Py_path_config.exec_prefix = _PyMem_RawWcsdup(L""); - _Py_path_config.module_search_path = _PyMem_RawWcsdup(path); - - PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - - if (_Py_path_config.prefix == NULL - || _Py_path_config.exec_prefix == NULL - || _Py_path_config.module_search_path == NULL) - { - path_out_of_memory(__func__); - } -} - - -void -Py_SetPythonHome(const wchar_t *home) -{ - if (home == NULL) { - return; - } - - PyMemAllocatorEx old_alloc; - _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - - PyMem_RawFree(_Py_path_config.home); - _Py_path_config.home = _PyMem_RawWcsdup(home); - - PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - - if (_Py_path_config.home == NULL) { - path_out_of_memory(__func__); - } -} - - -void -Py_SetProgramName(const wchar_t *program_name) -{ - if (program_name == NULL || program_name[0] == L'\0') { - return; - } - - PyMemAllocatorEx old_alloc; - _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - - PyMem_RawFree(_Py_path_config.program_name); - _Py_path_config.program_name = _PyMem_RawWcsdup(program_name); - - PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - - if (_Py_path_config.program_name == NULL) { - path_out_of_memory(__func__); - } -} - -void -_Py_SetProgramFullPath(const wchar_t *program_full_path) -{ - if (program_full_path == NULL || program_full_path[0] == L'\0') { - return; - } - - PyMemAllocatorEx old_alloc; - _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - - PyMem_RawFree(_Py_path_config.program_full_path); - _Py_path_config.program_full_path = _PyMem_RawWcsdup(program_full_path); - - PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - - if (_Py_path_config.program_full_path == NULL) { - path_out_of_memory(__func__); - } -} - - -wchar_t * -Py_GetPath(void) -{ - return _Py_path_config.module_search_path; -} - - -wchar_t * -Py_GetPrefix(void) -{ - return _Py_path_config.prefix; -} - - -wchar_t * -Py_GetExecPrefix(void) -{ - return _Py_path_config.exec_prefix; -} - - -wchar_t * -Py_GetProgramFullPath(void) -{ - return _Py_path_config.program_full_path; -} - - -wchar_t* -Py_GetPythonHome(void) -{ - return _Py_path_config.home; -} - - -wchar_t * -Py_GetProgramName(void) -{ - return _Py_path_config.program_name; -} - -/* Compute module search path from argv[0] or the current working - directory ("-m module" case) which will be prepended to sys.argv: - sys.path[0]. - - Return 1 if the path is correctly resolved and written into *path0_p. - - Return 0 if it fails to resolve the full path. For example, return 0 if the - current working directory has been removed (bpo-36236) or if argv is empty. - - Raise an exception and return -1 on error. - */ -int -_PyPathConfig_ComputeSysPath0(const PyWideStringList *argv, PyObject **path0_p) -{ - assert(_PyWideStringList_CheckConsistency(argv)); - - if (argv->length == 0) { - /* Leave sys.path unchanged if sys.argv is empty */ - return 0; - } - - wchar_t *argv0 = argv->items[0]; - int have_module_arg = (wcscmp(argv0, L"-m") == 0); - int have_script_arg = (!have_module_arg && (wcscmp(argv0, L"-c") != 0)); - - wchar_t *path0 = argv0; - Py_ssize_t n = 0; - -#ifdef HAVE_REALPATH - wchar_t fullpath[MAXPATHLEN]; -#elif defined(MS_WINDOWS) - wchar_t fullpath[MAX_PATH]; -#endif - - if (have_module_arg) { -#if defined(HAVE_REALPATH) || defined(MS_WINDOWS) - if (!_Py_wgetcwd(fullpath, Py_ARRAY_LENGTH(fullpath))) { - return 0; - } - path0 = fullpath; -#else - path0 = L"."; -#endif - n = wcslen(path0); - } - -#ifdef HAVE_READLINK - wchar_t link[MAXPATHLEN + 1]; - int nr = 0; - wchar_t path0copy[2 * MAXPATHLEN + 1]; - - if (have_script_arg) { - nr = _Py_wreadlink(path0, link, Py_ARRAY_LENGTH(link)); - } - if (nr > 0) { - /* It's a symlink */ - link[nr] = '\0'; - if (link[0] == SEP) { - path0 = link; /* Link to absolute path */ - } - else if (wcschr(link, SEP) == NULL) { - /* Link without path */ - } - else { - /* Must join(dirname(path0), link) */ - wchar_t *q = wcsrchr(path0, SEP); - if (q == NULL) { - /* path0 without path */ - path0 = link; - } - else { - /* Must make a copy, path0copy has room for 2 * MAXPATHLEN */ - wcsncpy(path0copy, path0, MAXPATHLEN); - q = wcsrchr(path0copy, SEP); - wcsncpy(q+1, link, MAXPATHLEN); - q[MAXPATHLEN + 1] = L'\0'; - path0 = path0copy; - } - } - } -#endif /* HAVE_READLINK */ - - wchar_t *p = NULL; - -#if SEP == '\\' - /* Special case for Microsoft filename syntax */ - if (have_script_arg) { - wchar_t *q; -#if defined(MS_WINDOWS) - /* Replace the first element in argv with the full path. */ - wchar_t *ptemp; - if (GetFullPathNameW(path0, - Py_ARRAY_LENGTH(fullpath), - fullpath, - &ptemp)) { - path0 = fullpath; - } -#endif - p = wcsrchr(path0, SEP); - /* Test for alternate separator */ - q = wcsrchr(p ? p : path0, '/'); - if (q != NULL) - p = q; - if (p != NULL) { - n = p + 1 - path0; - if (n > 1 && p[-1] != ':') - n--; /* Drop trailing separator */ - } - } -#else - /* All other filename syntaxes */ - if (have_script_arg) { -#if defined(HAVE_REALPATH) - if (_Py_wrealpath(path0, fullpath, Py_ARRAY_LENGTH(fullpath))) { - path0 = fullpath; - } -#endif - p = wcsrchr(path0, SEP); - } - if (p != NULL) { - n = p + 1 - path0; -#if SEP == '/' /* Special case for Unix filename syntax */ - if (n > 1) { - /* Drop trailing separator */ - n--; - } -#endif /* Unix */ - } -#endif /* All others */ - - PyObject *path0_obj = PyUnicode_FromWideChar(path0, n); - if (path0_obj == NULL) { - return -1; - } - - *path0_p = path0_obj; - return 1; -} - - -#ifdef MS_WINDOWS -#define WCSTOK wcstok_s -#else -#define WCSTOK wcstok -#endif - -/* Search for a prefix value in an environment file (pyvenv.cfg). - - - If found, copy it into *value_p: string which must be freed by - PyMem_RawFree(). - - If not found, *value_p is set to NULL. -*/ -PyStatus -_Py_FindEnvConfigValue(FILE *env_file, const wchar_t *key, - wchar_t **value_p) -{ - *value_p = NULL; - - char buffer[MAXPATHLEN * 2 + 1]; /* allow extra for key, '=', etc. */ - buffer[Py_ARRAY_LENGTH(buffer)-1] = '\0'; - - while (!feof(env_file)) { - char * p = fgets(buffer, Py_ARRAY_LENGTH(buffer) - 1, env_file); - - if (p == NULL) { - break; - } - - size_t n = strlen(p); - if (p[n - 1] != '\n') { - /* line has overflowed - bail */ - break; - } - if (p[0] == '#') { - /* Comment - skip */ - continue; - } - - wchar_t *tmpbuffer = _Py_DecodeUTF8_surrogateescape(buffer, n, NULL); - if (tmpbuffer) { - wchar_t * state; - wchar_t * tok = WCSTOK(tmpbuffer, L" \t\r\n", &state); - if ((tok != NULL) && !wcscmp(tok, key)) { - tok = WCSTOK(NULL, L" \t", &state); - if ((tok != NULL) && !wcscmp(tok, L"=")) { - tok = WCSTOK(NULL, L"\r\n", &state); - if (tok != NULL) { - *value_p = _PyMem_RawWcsdup(tok); - PyMem_RawFree(tmpbuffer); - - if (*value_p == NULL) { - return _PyStatus_NO_MEMORY(); - } - - /* found */ - return _PyStatus_OK(); - } - } - } - PyMem_RawFree(tmpbuffer); - } - } - - /* not found */ - return _PyStatus_OK(); -} - -#ifdef __cplusplus -} -#endif diff --git a/contrib/tools/python3/src/Python/preconfig.c b/contrib/tools/python3/src/Python/preconfig.c deleted file mode 100644 index ae1cc3f90fc..00000000000 --- a/contrib/tools/python3/src/Python/preconfig.c +++ /dev/null @@ -1,987 +0,0 @@ -#include "Python.h" -#include "pycore_getopt.h" // _PyOS_GetOpt() -#include "pycore_initconfig.h" // _PyArgv -#include "pycore_pymem.h" // _PyMem_GetAllocatorName() -#include "pycore_runtime.h" // _PyRuntime_Initialize() -#include <locale.h> // setlocale() - - -#define DECODE_LOCALE_ERR(NAME, LEN) \ - (((LEN) == -2) \ - ? _PyStatus_ERR("cannot decode " NAME) \ - : _PyStatus_NO_MEMORY()) - - -/* Forward declarations */ -static void -preconfig_copy(PyPreConfig *config, const PyPreConfig *config2); - - -/* --- File system encoding/errors -------------------------------- */ - -const char *Py_FileSystemDefaultEncoding = NULL; -int Py_HasFileSystemDefaultEncoding = 0; -const char *Py_FileSystemDefaultEncodeErrors = NULL; -int _Py_HasFileSystemDefaultEncodeErrors = 0; - -void -_Py_ClearFileSystemEncoding(void) -{ - if (!Py_HasFileSystemDefaultEncoding && Py_FileSystemDefaultEncoding) { - PyMem_RawFree((char*)Py_FileSystemDefaultEncoding); - Py_FileSystemDefaultEncoding = NULL; - } - if (!_Py_HasFileSystemDefaultEncodeErrors && Py_FileSystemDefaultEncodeErrors) { - PyMem_RawFree((char*)Py_FileSystemDefaultEncodeErrors); - Py_FileSystemDefaultEncodeErrors = NULL; - } -} - - -/* Set Py_FileSystemDefaultEncoding and Py_FileSystemDefaultEncodeErrors - global configuration variables to PyConfig.filesystem_encoding and - PyConfig.filesystem_errors (encoded to UTF-8). - - Function called by _PyUnicode_InitEncodings(). */ -int -_Py_SetFileSystemEncoding(const char *encoding, const char *errors) -{ - char *encoding2 = _PyMem_RawStrdup(encoding); - if (encoding2 == NULL) { - return -1; - } - - char *errors2 = _PyMem_RawStrdup(errors); - if (errors2 == NULL) { - PyMem_RawFree(encoding2); - return -1; - } - - _Py_ClearFileSystemEncoding(); - - Py_FileSystemDefaultEncoding = encoding2; - Py_HasFileSystemDefaultEncoding = 0; - - Py_FileSystemDefaultEncodeErrors = errors2; - _Py_HasFileSystemDefaultEncodeErrors = 0; - return 0; -} - - -/* --- _PyArgv ---------------------------------------------------- */ - -/* Decode bytes_argv using Py_DecodeLocale() */ -PyStatus -_PyArgv_AsWstrList(const _PyArgv *args, PyWideStringList *list) -{ - PyWideStringList wargv = _PyWideStringList_INIT; - if (args->use_bytes_argv) { - size_t size = sizeof(wchar_t*) * args->argc; - wargv.items = (wchar_t **)PyMem_RawMalloc(size); - if (wargv.items == NULL) { - return _PyStatus_NO_MEMORY(); - } - - for (Py_ssize_t i = 0; i < args->argc; i++) { - size_t len; - wchar_t *arg = Py_DecodeLocale(args->bytes_argv[i], &len); - if (arg == NULL) { - _PyWideStringList_Clear(&wargv); - return DECODE_LOCALE_ERR("command line arguments", - (Py_ssize_t)len); - } - wargv.items[i] = arg; - wargv.length++; - } - - _PyWideStringList_Clear(list); - *list = wargv; - } - else { - wargv.length = args->argc; - wargv.items = (wchar_t **)args->wchar_argv; - if (_PyWideStringList_Copy(list, &wargv) < 0) { - return _PyStatus_NO_MEMORY(); - } - } - return _PyStatus_OK(); -} - - -/* --- _PyPreCmdline ------------------------------------------------- */ - -void -_PyPreCmdline_Clear(_PyPreCmdline *cmdline) -{ - _PyWideStringList_Clear(&cmdline->argv); - _PyWideStringList_Clear(&cmdline->xoptions); -} - - -PyStatus -_PyPreCmdline_SetArgv(_PyPreCmdline *cmdline, const _PyArgv *args) -{ - return _PyArgv_AsWstrList(args, &cmdline->argv); -} - - -static void -precmdline_get_preconfig(_PyPreCmdline *cmdline, const PyPreConfig *config) -{ -#define COPY_ATTR(ATTR) \ - if (config->ATTR != -1) { \ - cmdline->ATTR = config->ATTR; \ - } - - COPY_ATTR(isolated); - COPY_ATTR(use_environment); - COPY_ATTR(dev_mode); - -#undef COPY_ATTR -} - - -static void -precmdline_set_preconfig(const _PyPreCmdline *cmdline, PyPreConfig *config) -{ -#define COPY_ATTR(ATTR) \ - config->ATTR = cmdline->ATTR - - COPY_ATTR(isolated); - COPY_ATTR(use_environment); - COPY_ATTR(dev_mode); - -#undef COPY_ATTR -} - - -PyStatus -_PyPreCmdline_SetConfig(const _PyPreCmdline *cmdline, PyConfig *config) -{ -#define COPY_ATTR(ATTR) \ - config->ATTR = cmdline->ATTR - - PyStatus status = _PyWideStringList_Extend(&config->xoptions, &cmdline->xoptions); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - COPY_ATTR(isolated); - COPY_ATTR(use_environment); - COPY_ATTR(dev_mode); - COPY_ATTR(warn_default_encoding); - return _PyStatus_OK(); - -#undef COPY_ATTR -} - - -/* Parse the command line arguments */ -static PyStatus -precmdline_parse_cmdline(_PyPreCmdline *cmdline) -{ - const PyWideStringList *argv = &cmdline->argv; - - _PyOS_ResetGetOpt(); - /* Don't log parsing errors into stderr here: PyConfig_Read() - is responsible for that */ - _PyOS_opterr = 0; - do { - int longindex = -1; - int c = _PyOS_GetOpt(argv->length, argv->items, &longindex); - - if (c == EOF || c == 'c' || c == 'm') { - break; - } - - switch (c) { - case 'E': - cmdline->use_environment = 0; - break; - - case 'I': - cmdline->isolated = 1; - break; - - case 'X': - { - PyStatus status = PyWideStringList_Append(&cmdline->xoptions, - _PyOS_optarg); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - break; - } - - default: - /* ignore other argument: - handled by PyConfig_Read() */ - break; - } - } while (1); - - return _PyStatus_OK(); -} - - -PyStatus -_PyPreCmdline_Read(_PyPreCmdline *cmdline, const PyPreConfig *preconfig) -{ - precmdline_get_preconfig(cmdline, preconfig); - - if (preconfig->parse_argv) { - PyStatus status = precmdline_parse_cmdline(cmdline); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - } - - /* isolated, use_environment */ - if (cmdline->isolated < 0) { - cmdline->isolated = 0; - } - if (cmdline->isolated > 0) { - cmdline->use_environment = 0; - } - if (cmdline->use_environment < 0) { - cmdline->use_environment = 0; - } - - /* dev_mode */ - if ((cmdline->dev_mode < 0) - && (_Py_get_xoption(&cmdline->xoptions, L"dev") - || _Py_GetEnv(cmdline->use_environment, "PYTHONDEVMODE"))) - { - cmdline->dev_mode = 1; - } - if (cmdline->dev_mode < 0) { - cmdline->dev_mode = 0; - } - - // warn_default_encoding - if (_Py_get_xoption(&cmdline->xoptions, L"warn_default_encoding") - || _Py_GetEnv(cmdline->use_environment, "PYTHONWARNDEFAULTENCODING")) - { - cmdline->warn_default_encoding = 1; - } - - assert(cmdline->use_environment >= 0); - assert(cmdline->isolated >= 0); - assert(cmdline->dev_mode >= 0); - assert(cmdline->warn_default_encoding >= 0); - - return _PyStatus_OK(); -} - - -/* --- PyPreConfig ----------------------------------------------- */ - - -void -_PyPreConfig_InitCompatConfig(PyPreConfig *config) -{ - memset(config, 0, sizeof(*config)); - - config->_config_init = (int)_PyConfig_INIT_COMPAT; - config->parse_argv = 0; - config->isolated = -1; - config->use_environment = -1; - config->configure_locale = 1; - - /* bpo-36443: C locale coercion (PEP 538) and UTF-8 Mode (PEP 540) - are disabled by default using the Compat configuration. - - Py_UTF8Mode=1 enables the UTF-8 mode. PYTHONUTF8 environment variable - is ignored (even if use_environment=1). */ - config->utf8_mode = 0; - config->coerce_c_locale = 0; - config->coerce_c_locale_warn = 0; - - config->dev_mode = -1; -#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS - /* bpo-40512: pymalloc is not compatible with subinterpreters, - force usage of libc malloc() which is thread-safe. */ -#ifdef Py_DEBUG - config->allocator = PYMEM_ALLOCATOR_MALLOC_DEBUG; -#else - config->allocator = PYMEM_ALLOCATOR_MALLOC; -#endif -#else - config->allocator = PYMEM_ALLOCATOR_NOT_SET; -#endif -#ifdef MS_WINDOWS - config->legacy_windows_fs_encoding = -1; -#endif -} - - -void -PyPreConfig_InitPythonConfig(PyPreConfig *config) -{ - _PyPreConfig_InitCompatConfig(config); - - config->_config_init = (int)_PyConfig_INIT_PYTHON; - config->isolated = 0; - config->parse_argv = 1; - config->use_environment = 1; - /* Set to -1 to enable C locale coercion (PEP 538) and UTF-8 Mode (PEP 540) - depending on the LC_CTYPE locale, PYTHONUTF8 and PYTHONCOERCECLOCALE - environment variables. */ - config->coerce_c_locale = -1; - config->coerce_c_locale_warn = -1; - config->utf8_mode = -1; -#ifdef MS_WINDOWS - config->legacy_windows_fs_encoding = 0; -#endif -} - - -void -PyPreConfig_InitIsolatedConfig(PyPreConfig *config) -{ - _PyPreConfig_InitCompatConfig(config); - - config->_config_init = (int)_PyConfig_INIT_ISOLATED; - config->configure_locale = 0; - config->isolated = 1; - config->use_environment = 0; - config->utf8_mode = 0; - config->dev_mode = 0; -#ifdef MS_WINDOWS - config->legacy_windows_fs_encoding = 0; -#endif -} - - -PyStatus -_PyPreConfig_InitFromPreConfig(PyPreConfig *config, - const PyPreConfig *config2) -{ - PyPreConfig_InitPythonConfig(config); - preconfig_copy(config, config2); - return _PyStatus_OK(); -} - - -void -_PyPreConfig_InitFromConfig(PyPreConfig *preconfig, const PyConfig *config) -{ - _PyConfigInitEnum config_init = (_PyConfigInitEnum)config->_config_init; - switch (config_init) { - case _PyConfig_INIT_PYTHON: - PyPreConfig_InitPythonConfig(preconfig); - break; - case _PyConfig_INIT_ISOLATED: - PyPreConfig_InitIsolatedConfig(preconfig); - break; - case _PyConfig_INIT_COMPAT: - default: - _PyPreConfig_InitCompatConfig(preconfig); - } - - _PyPreConfig_GetConfig(preconfig, config); -} - - -static void -preconfig_copy(PyPreConfig *config, const PyPreConfig *config2) -{ -#define COPY_ATTR(ATTR) config->ATTR = config2->ATTR - - COPY_ATTR(_config_init); - COPY_ATTR(parse_argv); - COPY_ATTR(isolated); - COPY_ATTR(use_environment); - COPY_ATTR(configure_locale); - COPY_ATTR(dev_mode); - COPY_ATTR(coerce_c_locale); - COPY_ATTR(coerce_c_locale_warn); - COPY_ATTR(utf8_mode); - COPY_ATTR(allocator); -#ifdef MS_WINDOWS - COPY_ATTR(legacy_windows_fs_encoding); -#endif - -#undef COPY_ATTR -} - - -PyObject* -_PyPreConfig_AsDict(const PyPreConfig *config) -{ - PyObject *dict; - - dict = PyDict_New(); - if (dict == NULL) { - return NULL; - } - -#define SET_ITEM_INT(ATTR) \ - do { \ - PyObject *obj = PyLong_FromLong(config->ATTR); \ - if (obj == NULL) { \ - goto fail; \ - } \ - int res = PyDict_SetItemString(dict, #ATTR, obj); \ - Py_DECREF(obj); \ - if (res < 0) { \ - goto fail; \ - } \ - } while (0) - - SET_ITEM_INT(_config_init); - SET_ITEM_INT(parse_argv); - SET_ITEM_INT(isolated); - SET_ITEM_INT(use_environment); - SET_ITEM_INT(configure_locale); - SET_ITEM_INT(coerce_c_locale); - SET_ITEM_INT(coerce_c_locale_warn); - SET_ITEM_INT(utf8_mode); -#ifdef MS_WINDOWS - SET_ITEM_INT(legacy_windows_fs_encoding); -#endif - SET_ITEM_INT(dev_mode); - SET_ITEM_INT(allocator); - return dict; - -fail: - Py_DECREF(dict); - return NULL; - -#undef SET_ITEM_INT -} - - -void -_PyPreConfig_GetConfig(PyPreConfig *preconfig, const PyConfig *config) -{ -#define COPY_ATTR(ATTR) \ - if (config->ATTR != -1) { \ - preconfig->ATTR = config->ATTR; \ - } - - COPY_ATTR(parse_argv); - COPY_ATTR(isolated); - COPY_ATTR(use_environment); - COPY_ATTR(dev_mode); - -#undef COPY_ATTR -} - - -static void -preconfig_get_global_vars(PyPreConfig *config) -{ - if (config->_config_init != _PyConfig_INIT_COMPAT) { - /* Python and Isolated configuration ignore global variables */ - return; - } - -#define COPY_FLAG(ATTR, VALUE) \ - if (config->ATTR < 0) { \ - config->ATTR = VALUE; \ - } -#define COPY_NOT_FLAG(ATTR, VALUE) \ - if (config->ATTR < 0) { \ - config->ATTR = !(VALUE); \ - } - - COPY_FLAG(isolated, Py_IsolatedFlag); - COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag); - if (Py_UTF8Mode > 0) { - config->utf8_mode = Py_UTF8Mode; - } -#ifdef MS_WINDOWS - COPY_FLAG(legacy_windows_fs_encoding, Py_LegacyWindowsFSEncodingFlag); -#endif - -#undef COPY_FLAG -#undef COPY_NOT_FLAG -} - - -static void -preconfig_set_global_vars(const PyPreConfig *config) -{ -#define COPY_FLAG(ATTR, VAR) \ - if (config->ATTR >= 0) { \ - VAR = config->ATTR; \ - } -#define COPY_NOT_FLAG(ATTR, VAR) \ - if (config->ATTR >= 0) { \ - VAR = !config->ATTR; \ - } - - COPY_FLAG(isolated, Py_IsolatedFlag); - COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag); -#ifdef MS_WINDOWS - COPY_FLAG(legacy_windows_fs_encoding, Py_LegacyWindowsFSEncodingFlag); -#endif - COPY_FLAG(utf8_mode, Py_UTF8Mode); - -#undef COPY_FLAG -#undef COPY_NOT_FLAG -} - - -const char* -_Py_GetEnv(int use_environment, const char *name) -{ - assert(use_environment >= 0); - - if (!use_environment) { - return NULL; - } - - const char *var = getenv(name); - if (var && var[0] != '\0') { - return var; - } - else { - return NULL; - } -} - - -int -_Py_str_to_int(const char *str, int *result) -{ - const char *endptr = str; - errno = 0; - long value = strtol(str, (char **)&endptr, 10); - if (*endptr != '\0' || errno == ERANGE) { - return -1; - } - if (value < INT_MIN || value > INT_MAX) { - return -1; - } - - *result = (int)value; - return 0; -} - - -void -_Py_get_env_flag(int use_environment, int *flag, const char *name) -{ - const char *var = _Py_GetEnv(use_environment, name); - if (!var) { - return; - } - int value; - if (_Py_str_to_int(var, &value) < 0 || value < 0) { - /* PYTHONDEBUG=text and PYTHONDEBUG=-2 behave as PYTHONDEBUG=1 */ - value = 1; - } - if (*flag < value) { - *flag = value; - } -} - - -const wchar_t* -_Py_get_xoption(const PyWideStringList *xoptions, const wchar_t *name) -{ - for (Py_ssize_t i=0; i < xoptions->length; i++) { - const wchar_t *option = xoptions->items[i]; - size_t len; - wchar_t *sep = wcschr(option, L'='); - if (sep != NULL) { - len = (sep - option); - } - else { - len = wcslen(option); - } - if (wcsncmp(option, name, len) == 0 && name[len] == L'\0') { - return option; - } - } - return NULL; -} - - -static PyStatus -preconfig_init_utf8_mode(PyPreConfig *config, const _PyPreCmdline *cmdline) -{ -#ifdef MS_WINDOWS - if (config->legacy_windows_fs_encoding) { - config->utf8_mode = 0; - } -#endif - - if (config->utf8_mode >= 0) { - return _PyStatus_OK(); - } - - const wchar_t *xopt; - xopt = _Py_get_xoption(&cmdline->xoptions, L"utf8"); - if (xopt) { - wchar_t *sep = wcschr(xopt, L'='); - if (sep) { - xopt = sep + 1; - if (wcscmp(xopt, L"1") == 0) { - config->utf8_mode = 1; - } - else if (wcscmp(xopt, L"0") == 0) { - config->utf8_mode = 0; - } - else { - return _PyStatus_ERR("invalid -X utf8 option value"); - } - } - else { - config->utf8_mode = 1; - } - return _PyStatus_OK(); - } - - const char *opt = _Py_GetEnv(config->use_environment, "PYTHONUTF8"); - if (opt) { - if (strcmp(opt, "1") == 0) { - config->utf8_mode = 1; - } - else if (strcmp(opt, "0") == 0) { - config->utf8_mode = 0; - } - else { - return _PyStatus_ERR("invalid PYTHONUTF8 environment " - "variable value"); - } - return _PyStatus_OK(); - } - - -#ifndef MS_WINDOWS - if (config->utf8_mode < 0) { - /* The C locale and the POSIX locale enable the UTF-8 Mode (PEP 540) */ - const char *ctype_loc = setlocale(LC_CTYPE, NULL); - if (ctype_loc != NULL - && (strcmp(ctype_loc, "C") == 0 - || strcmp(ctype_loc, "POSIX") == 0)) - { - config->utf8_mode = 1; - } - } -#endif - - if (config->utf8_mode < 0) { - config->utf8_mode = 0; - } - return _PyStatus_OK(); -} - - -static void -preconfig_init_coerce_c_locale(PyPreConfig *config) -{ - if (!config->configure_locale) { - config->coerce_c_locale = 0; - config->coerce_c_locale_warn = 0; - return; - } - - const char *env = _Py_GetEnv(config->use_environment, "PYTHONCOERCECLOCALE"); - if (env) { - if (strcmp(env, "0") == 0) { - if (config->coerce_c_locale < 0) { - config->coerce_c_locale = 0; - } - } - else if (strcmp(env, "warn") == 0) { - if (config->coerce_c_locale_warn < 0) { - config->coerce_c_locale_warn = 1; - } - } - else { - if (config->coerce_c_locale < 0) { - config->coerce_c_locale = 1; - } - } - } - - /* Test if coerce_c_locale equals to -1 or equals to 1: - PYTHONCOERCECLOCALE=1 doesn't imply that the C locale is always coerced. - It is only coerced if if the LC_CTYPE locale is "C". */ - if (config->coerce_c_locale < 0 || config->coerce_c_locale == 1) { - /* The C locale enables the C locale coercion (PEP 538) */ - if (_Py_LegacyLocaleDetected(0)) { - config->coerce_c_locale = 2; - } - else { - config->coerce_c_locale = 0; - } - } - - if (config->coerce_c_locale_warn < 0) { - config->coerce_c_locale_warn = 0; - } -} - - -static PyStatus -preconfig_init_allocator(PyPreConfig *config) -{ - if (config->allocator == PYMEM_ALLOCATOR_NOT_SET) { - /* bpo-34247. The PYTHONMALLOC environment variable has the priority - over PYTHONDEV env var and "-X dev" command line option. - For example, PYTHONMALLOC=malloc PYTHONDEVMODE=1 sets the memory - allocators to "malloc" (and not to "debug"). */ - const char *envvar = _Py_GetEnv(config->use_environment, "PYTHONMALLOC"); - if (envvar) { - PyMemAllocatorName name; - if (_PyMem_GetAllocatorName(envvar, &name) < 0) { - return _PyStatus_ERR("PYTHONMALLOC: unknown allocator"); - } - config->allocator = (int)name; - } - } - - if (config->dev_mode && config->allocator == PYMEM_ALLOCATOR_NOT_SET) { - config->allocator = PYMEM_ALLOCATOR_DEBUG; - } - return _PyStatus_OK(); -} - - -static PyStatus -preconfig_read(PyPreConfig *config, _PyPreCmdline *cmdline) -{ - PyStatus status; - - status = _PyPreCmdline_Read(cmdline, config); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - precmdline_set_preconfig(cmdline, config); - - /* legacy_windows_fs_encoding, coerce_c_locale, utf8_mode */ -#ifdef MS_WINDOWS - _Py_get_env_flag(config->use_environment, - &config->legacy_windows_fs_encoding, - "PYTHONLEGACYWINDOWSFSENCODING"); -#endif - - preconfig_init_coerce_c_locale(config); - - status = preconfig_init_utf8_mode(config, cmdline); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - /* allocator */ - status = preconfig_init_allocator(config); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - assert(config->coerce_c_locale >= 0); - assert(config->coerce_c_locale_warn >= 0); -#ifdef MS_WINDOWS - assert(config->legacy_windows_fs_encoding >= 0); -#endif - assert(config->utf8_mode >= 0); - assert(config->isolated >= 0); - assert(config->use_environment >= 0); - assert(config->dev_mode >= 0); - - return _PyStatus_OK(); -} - - -/* Read the configuration from: - - - command line arguments - - environment variables - - Py_xxx global configuration variables - - the LC_CTYPE locale */ -PyStatus -_PyPreConfig_Read(PyPreConfig *config, const _PyArgv *args) -{ - PyStatus status; - - status = _PyRuntime_Initialize(); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - preconfig_get_global_vars(config); - - /* Copy LC_CTYPE locale, since it's modified later */ - const char *loc = setlocale(LC_CTYPE, NULL); - if (loc == NULL) { - return _PyStatus_ERR("failed to LC_CTYPE locale"); - } - char *init_ctype_locale = _PyMem_RawStrdup(loc); - if (init_ctype_locale == NULL) { - return _PyStatus_NO_MEMORY(); - } - - /* Save the config to be able to restore it if encodings change */ - PyPreConfig save_config; - - status = _PyPreConfig_InitFromPreConfig(&save_config, config); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - /* Set LC_CTYPE to the user preferred locale */ - if (config->configure_locale) { - _Py_SetLocaleFromEnv(LC_CTYPE); - } - - _PyPreCmdline cmdline = _PyPreCmdline_INIT; - int init_utf8_mode = Py_UTF8Mode; -#ifdef MS_WINDOWS - int init_legacy_encoding = Py_LegacyWindowsFSEncodingFlag; -#endif - - int locale_coerced = 0; - int loops = 0; - - while (1) { - int utf8_mode = config->utf8_mode; - - /* Watchdog to prevent an infinite loop */ - loops++; - if (loops == 3) { - status = _PyStatus_ERR("Encoding changed twice while " - "reading the configuration"); - goto done; - } - - /* bpo-34207: Py_DecodeLocale() and Py_EncodeLocale() depend - on Py_UTF8Mode and Py_LegacyWindowsFSEncodingFlag. */ - Py_UTF8Mode = config->utf8_mode; -#ifdef MS_WINDOWS - Py_LegacyWindowsFSEncodingFlag = config->legacy_windows_fs_encoding; -#endif - - if (args) { - // Set command line arguments at each iteration. If they are bytes - // strings, they are decoded from the new encoding. - status = _PyPreCmdline_SetArgv(&cmdline, args); - if (_PyStatus_EXCEPTION(status)) { - goto done; - } - } - - status = preconfig_read(config, &cmdline); - if (_PyStatus_EXCEPTION(status)) { - goto done; - } - - /* The legacy C locale assumes ASCII as the default text encoding, which - * causes problems not only for the CPython runtime, but also other - * components like GNU readline. - * - * Accordingly, when the CLI detects it, it attempts to coerce it to a - * more capable UTF-8 based alternative. - * - * See the documentation of the PYTHONCOERCECLOCALE setting for more - * details. - */ - int encoding_changed = 0; - if (config->coerce_c_locale && !locale_coerced) { - locale_coerced = 1; - _Py_CoerceLegacyLocale(0); - encoding_changed = 1; - } - - if (utf8_mode == -1) { - if (config->utf8_mode == 1) { - /* UTF-8 Mode enabled */ - encoding_changed = 1; - } - } - else { - if (config->utf8_mode != utf8_mode) { - encoding_changed = 1; - } - } - - if (!encoding_changed) { - break; - } - - /* Reset the configuration before reading again the configuration, - just keep UTF-8 Mode and coerce C locale value. */ - int new_utf8_mode = config->utf8_mode; - int new_coerce_c_locale = config->coerce_c_locale; - preconfig_copy(config, &save_config); - config->utf8_mode = new_utf8_mode; - config->coerce_c_locale = new_coerce_c_locale; - - /* The encoding changed: read again the configuration - with the new encoding */ - } - status = _PyStatus_OK(); - -done: - if (init_ctype_locale != NULL) { - setlocale(LC_CTYPE, init_ctype_locale); - PyMem_RawFree(init_ctype_locale); - } - Py_UTF8Mode = init_utf8_mode ; -#ifdef MS_WINDOWS - Py_LegacyWindowsFSEncodingFlag = init_legacy_encoding; -#endif - _PyPreCmdline_Clear(&cmdline); - return status; -} - - -/* Write the pre-configuration: - - - set the memory allocators - - set Py_xxx global configuration variables - - set the LC_CTYPE locale (coerce C locale, PEP 538) and set the UTF-8 mode - (PEP 540) - - The applied configuration is written into _PyRuntime.preconfig. - If the C locale cannot be coerced, set coerce_c_locale to 0. - - Do nothing if called after Py_Initialize(): ignore the new - pre-configuration. */ -PyStatus -_PyPreConfig_Write(const PyPreConfig *src_config) -{ - PyPreConfig config; - - PyStatus status = _PyPreConfig_InitFromPreConfig(&config, src_config); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - if (_PyRuntime.core_initialized) { - /* bpo-34008: Calling this functions after Py_Initialize() ignores - the new configuration. */ - return _PyStatus_OK(); - } - - PyMemAllocatorName name = (PyMemAllocatorName)config.allocator; - if (name != PYMEM_ALLOCATOR_NOT_SET) { - if (_PyMem_SetupAllocators(name) < 0) { - return _PyStatus_ERR("Unknown PYTHONMALLOC allocator"); - } - } - - preconfig_set_global_vars(&config); - - if (config.configure_locale) { - if (config.coerce_c_locale) { - if (!_Py_CoerceLegacyLocale(config.coerce_c_locale_warn)) { - /* C locale not coerced */ - config.coerce_c_locale = 0; - } - } - - /* Set LC_CTYPE to the user preferred locale */ - _Py_SetLocaleFromEnv(LC_CTYPE); - } - - /* Write the new pre-configuration into _PyRuntime */ - preconfig_copy(&_PyRuntime.preconfig, &config); - - return _PyStatus_OK(); -} diff --git a/contrib/tools/python3/src/Python/pyarena.c b/contrib/tools/python3/src/Python/pyarena.c deleted file mode 100644 index ead03370d15..00000000000 --- a/contrib/tools/python3/src/Python/pyarena.c +++ /dev/null @@ -1,211 +0,0 @@ -#include "Python.h" -#include "pycore_pyarena.h" // PyArena - -/* A simple arena block structure. - - Measurements with standard library modules suggest the average - allocation is about 20 bytes and that most compiles use a single - block. - - TODO(jhylton): Think about a realloc API, maybe just for the last - allocation? -*/ - -#define DEFAULT_BLOCK_SIZE 8192 -#define ALIGNMENT 8 - -typedef struct _block { - /* Total number of bytes owned by this block available to pass out. - * Read-only after initialization. The first such byte starts at - * ab_mem. - */ - size_t ab_size; - - /* Total number of bytes already passed out. The next byte available - * to pass out starts at ab_mem + ab_offset. - */ - size_t ab_offset; - - /* An arena maintains a singly-linked, NULL-terminated list of - * all blocks owned by the arena. These are linked via the - * ab_next member. - */ - struct _block *ab_next; - - /* Pointer to the first allocatable byte owned by this block. Read- - * only after initialization. - */ - void *ab_mem; -} block; - -/* The arena manages two kinds of memory, blocks of raw memory - and a list of PyObject* pointers. PyObjects are decrefed - when the arena is freed. -*/ - -struct _arena { - /* Pointer to the first block allocated for the arena, never NULL. - It is used only to find the first block when the arena is - being freed. - */ - block *a_head; - - /* Pointer to the block currently used for allocation. Its - ab_next field should be NULL. If it is not-null after a - call to block_alloc(), it means a new block has been allocated - and a_cur should be reset to point it. - */ - block *a_cur; - - /* A Python list object containing references to all the PyObject - pointers associated with this arena. They will be DECREFed - when the arena is freed. - */ - PyObject *a_objects; - -#if defined(Py_DEBUG) - /* Debug output */ - size_t total_allocs; - size_t total_size; - size_t total_blocks; - size_t total_block_size; - size_t total_big_blocks; -#endif -}; - -static block * -block_new(size_t size) -{ - /* Allocate header and block as one unit. - ab_mem points just past header. */ - block *b = (block *)PyMem_Malloc(sizeof(block) + size); - if (!b) - return NULL; - b->ab_size = size; - b->ab_mem = (void *)(b + 1); - b->ab_next = NULL; - b->ab_offset = (char *)_Py_ALIGN_UP(b->ab_mem, ALIGNMENT) - - (char *)(b->ab_mem); - return b; -} - -static void -block_free(block *b) { - while (b) { - block *next = b->ab_next; - PyMem_Free(b); - b = next; - } -} - -static void * -block_alloc(block *b, size_t size) -{ - void *p; - assert(b); - size = _Py_SIZE_ROUND_UP(size, ALIGNMENT); - if (b->ab_offset + size > b->ab_size) { - /* If we need to allocate more memory than will fit in - the default block, allocate a one-off block that is - exactly the right size. */ - /* TODO(jhylton): Think about space waste at end of block */ - block *newbl = block_new( - size < DEFAULT_BLOCK_SIZE ? - DEFAULT_BLOCK_SIZE : size); - if (!newbl) - return NULL; - assert(!b->ab_next); - b->ab_next = newbl; - b = newbl; - } - - assert(b->ab_offset + size <= b->ab_size); - p = (void *)(((char *)b->ab_mem) + b->ab_offset); - b->ab_offset += size; - return p; -} - -PyArena * -_PyArena_New(void) -{ - PyArena* arena = (PyArena *)PyMem_Malloc(sizeof(PyArena)); - if (!arena) - return (PyArena*)PyErr_NoMemory(); - - arena->a_head = block_new(DEFAULT_BLOCK_SIZE); - arena->a_cur = arena->a_head; - if (!arena->a_head) { - PyMem_Free((void *)arena); - return (PyArena*)PyErr_NoMemory(); - } - arena->a_objects = PyList_New(0); - if (!arena->a_objects) { - block_free(arena->a_head); - PyMem_Free((void *)arena); - return (PyArena*)PyErr_NoMemory(); - } -#if defined(Py_DEBUG) - arena->total_allocs = 0; - arena->total_size = 0; - arena->total_blocks = 1; - arena->total_block_size = DEFAULT_BLOCK_SIZE; - arena->total_big_blocks = 0; -#endif - return arena; -} - -void -_PyArena_Free(PyArena *arena) -{ - assert(arena); -#if defined(Py_DEBUG) - /* - fprintf(stderr, - "alloc=%zu size=%zu blocks=%zu block_size=%zu big=%zu objects=%zu\n", - arena->total_allocs, arena->total_size, arena->total_blocks, - arena->total_block_size, arena->total_big_blocks, - PyList_Size(arena->a_objects)); - */ -#endif - block_free(arena->a_head); - /* This property normally holds, except when the code being compiled - is sys.getobjects(0), in which case there will be two references. - assert(arena->a_objects->ob_refcnt == 1); - */ - - Py_DECREF(arena->a_objects); - PyMem_Free(arena); -} - -void * -_PyArena_Malloc(PyArena *arena, size_t size) -{ - void *p = block_alloc(arena->a_cur, size); - if (!p) - return PyErr_NoMemory(); -#if defined(Py_DEBUG) - arena->total_allocs++; - arena->total_size += size; -#endif - /* Reset cur if we allocated a new block. */ - if (arena->a_cur->ab_next) { - arena->a_cur = arena->a_cur->ab_next; -#if defined(Py_DEBUG) - arena->total_blocks++; - arena->total_block_size += arena->a_cur->ab_size; - if (arena->a_cur->ab_size > DEFAULT_BLOCK_SIZE) - ++arena->total_big_blocks; -#endif - } - return p; -} - -int -_PyArena_AddPyObject(PyArena *arena, PyObject *obj) -{ - int r = PyList_Append(arena->a_objects, obj); - if (r >= 0) { - Py_DECREF(obj); - } - return r; -} diff --git a/contrib/tools/python3/src/Python/pyctype.c b/contrib/tools/python3/src/Python/pyctype.c deleted file mode 100644 index da117d58fd0..00000000000 --- a/contrib/tools/python3/src/Python/pyctype.c +++ /dev/null @@ -1,214 +0,0 @@ -#include "Python.h" - -/* Our own locale-independent ctype.h-like macros */ - -const unsigned int _Py_ctype_table[256] = { - 0, /* 0x0 '\x00' */ - 0, /* 0x1 '\x01' */ - 0, /* 0x2 '\x02' */ - 0, /* 0x3 '\x03' */ - 0, /* 0x4 '\x04' */ - 0, /* 0x5 '\x05' */ - 0, /* 0x6 '\x06' */ - 0, /* 0x7 '\x07' */ - 0, /* 0x8 '\x08' */ - PY_CTF_SPACE, /* 0x9 '\t' */ - PY_CTF_SPACE, /* 0xa '\n' */ - PY_CTF_SPACE, /* 0xb '\v' */ - PY_CTF_SPACE, /* 0xc '\f' */ - PY_CTF_SPACE, /* 0xd '\r' */ - 0, /* 0xe '\x0e' */ - 0, /* 0xf '\x0f' */ - 0, /* 0x10 '\x10' */ - 0, /* 0x11 '\x11' */ - 0, /* 0x12 '\x12' */ - 0, /* 0x13 '\x13' */ - 0, /* 0x14 '\x14' */ - 0, /* 0x15 '\x15' */ - 0, /* 0x16 '\x16' */ - 0, /* 0x17 '\x17' */ - 0, /* 0x18 '\x18' */ - 0, /* 0x19 '\x19' */ - 0, /* 0x1a '\x1a' */ - 0, /* 0x1b '\x1b' */ - 0, /* 0x1c '\x1c' */ - 0, /* 0x1d '\x1d' */ - 0, /* 0x1e '\x1e' */ - 0, /* 0x1f '\x1f' */ - PY_CTF_SPACE, /* 0x20 ' ' */ - 0, /* 0x21 '!' */ - 0, /* 0x22 '"' */ - 0, /* 0x23 '#' */ - 0, /* 0x24 '$' */ - 0, /* 0x25 '%' */ - 0, /* 0x26 '&' */ - 0, /* 0x27 "'" */ - 0, /* 0x28 '(' */ - 0, /* 0x29 ')' */ - 0, /* 0x2a '*' */ - 0, /* 0x2b '+' */ - 0, /* 0x2c ',' */ - 0, /* 0x2d '-' */ - 0, /* 0x2e '.' */ - 0, /* 0x2f '/' */ - PY_CTF_DIGIT|PY_CTF_XDIGIT, /* 0x30 '0' */ - PY_CTF_DIGIT|PY_CTF_XDIGIT, /* 0x31 '1' */ - PY_CTF_DIGIT|PY_CTF_XDIGIT, /* 0x32 '2' */ - PY_CTF_DIGIT|PY_CTF_XDIGIT, /* 0x33 '3' */ - PY_CTF_DIGIT|PY_CTF_XDIGIT, /* 0x34 '4' */ - PY_CTF_DIGIT|PY_CTF_XDIGIT, /* 0x35 '5' */ - PY_CTF_DIGIT|PY_CTF_XDIGIT, /* 0x36 '6' */ - PY_CTF_DIGIT|PY_CTF_XDIGIT, /* 0x37 '7' */ - PY_CTF_DIGIT|PY_CTF_XDIGIT, /* 0x38 '8' */ - PY_CTF_DIGIT|PY_CTF_XDIGIT, /* 0x39 '9' */ - 0, /* 0x3a ':' */ - 0, /* 0x3b ';' */ - 0, /* 0x3c '<' */ - 0, /* 0x3d '=' */ - 0, /* 0x3e '>' */ - 0, /* 0x3f '?' */ - 0, /* 0x40 '@' */ - PY_CTF_UPPER|PY_CTF_XDIGIT, /* 0x41 'A' */ - PY_CTF_UPPER|PY_CTF_XDIGIT, /* 0x42 'B' */ - PY_CTF_UPPER|PY_CTF_XDIGIT, /* 0x43 'C' */ - PY_CTF_UPPER|PY_CTF_XDIGIT, /* 0x44 'D' */ - PY_CTF_UPPER|PY_CTF_XDIGIT, /* 0x45 'E' */ - PY_CTF_UPPER|PY_CTF_XDIGIT, /* 0x46 'F' */ - PY_CTF_UPPER, /* 0x47 'G' */ - PY_CTF_UPPER, /* 0x48 'H' */ - PY_CTF_UPPER, /* 0x49 'I' */ - PY_CTF_UPPER, /* 0x4a 'J' */ - PY_CTF_UPPER, /* 0x4b 'K' */ - PY_CTF_UPPER, /* 0x4c 'L' */ - PY_CTF_UPPER, /* 0x4d 'M' */ - PY_CTF_UPPER, /* 0x4e 'N' */ - PY_CTF_UPPER, /* 0x4f 'O' */ - PY_CTF_UPPER, /* 0x50 'P' */ - PY_CTF_UPPER, /* 0x51 'Q' */ - PY_CTF_UPPER, /* 0x52 'R' */ - PY_CTF_UPPER, /* 0x53 'S' */ - PY_CTF_UPPER, /* 0x54 'T' */ - PY_CTF_UPPER, /* 0x55 'U' */ - PY_CTF_UPPER, /* 0x56 'V' */ - PY_CTF_UPPER, /* 0x57 'W' */ - PY_CTF_UPPER, /* 0x58 'X' */ - PY_CTF_UPPER, /* 0x59 'Y' */ - PY_CTF_UPPER, /* 0x5a 'Z' */ - 0, /* 0x5b '[' */ - 0, /* 0x5c '\\' */ - 0, /* 0x5d ']' */ - 0, /* 0x5e '^' */ - 0, /* 0x5f '_' */ - 0, /* 0x60 '`' */ - PY_CTF_LOWER|PY_CTF_XDIGIT, /* 0x61 'a' */ - PY_CTF_LOWER|PY_CTF_XDIGIT, /* 0x62 'b' */ - PY_CTF_LOWER|PY_CTF_XDIGIT, /* 0x63 'c' */ - PY_CTF_LOWER|PY_CTF_XDIGIT, /* 0x64 'd' */ - PY_CTF_LOWER|PY_CTF_XDIGIT, /* 0x65 'e' */ - PY_CTF_LOWER|PY_CTF_XDIGIT, /* 0x66 'f' */ - PY_CTF_LOWER, /* 0x67 'g' */ - PY_CTF_LOWER, /* 0x68 'h' */ - PY_CTF_LOWER, /* 0x69 'i' */ - PY_CTF_LOWER, /* 0x6a 'j' */ - PY_CTF_LOWER, /* 0x6b 'k' */ - PY_CTF_LOWER, /* 0x6c 'l' */ - PY_CTF_LOWER, /* 0x6d 'm' */ - PY_CTF_LOWER, /* 0x6e 'n' */ - PY_CTF_LOWER, /* 0x6f 'o' */ - PY_CTF_LOWER, /* 0x70 'p' */ - PY_CTF_LOWER, /* 0x71 'q' */ - PY_CTF_LOWER, /* 0x72 'r' */ - PY_CTF_LOWER, /* 0x73 's' */ - PY_CTF_LOWER, /* 0x74 't' */ - PY_CTF_LOWER, /* 0x75 'u' */ - PY_CTF_LOWER, /* 0x76 'v' */ - PY_CTF_LOWER, /* 0x77 'w' */ - PY_CTF_LOWER, /* 0x78 'x' */ - PY_CTF_LOWER, /* 0x79 'y' */ - PY_CTF_LOWER, /* 0x7a 'z' */ - 0, /* 0x7b '{' */ - 0, /* 0x7c '|' */ - 0, /* 0x7d '}' */ - 0, /* 0x7e '~' */ - 0, /* 0x7f '\x7f' */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - - -const unsigned char _Py_ctype_tolower[256] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, - 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, - 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, - 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, - 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, - 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, - 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, - 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, - 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, - 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, - 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, - 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, - 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, - 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, - 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, - 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, - 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, - 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, - 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, - 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, - 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, - 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, - 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, - 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, - 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, - 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, - 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, - 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, -}; - -const unsigned char _Py_ctype_toupper[256] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, - 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, - 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, - 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, - 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, - 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, - 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, - 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, - 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, - 0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, - 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, - 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, - 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, - 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, - 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, - 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, - 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, - 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, - 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, - 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, - 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, - 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, - 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, - 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, - 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, - 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, -}; - diff --git a/contrib/tools/python3/src/Python/pyfpe.c b/contrib/tools/python3/src/Python/pyfpe.c deleted file mode 100644 index 31ef5d73b70..00000000000 --- a/contrib/tools/python3/src/Python/pyfpe.c +++ /dev/null @@ -1,15 +0,0 @@ -/* These variables used to be used when Python was built with --with-fpectl, - * but support for that was dropped in 3.7. We continue to define them, - * though, because they may be referenced by extensions using the stable ABI. - */ - -#include "setjmp.h" - -jmp_buf PyFPE_jbuf; -int PyFPE_counter; - -double -PyFPE_dummy(void *dummy) -{ - return 1.0; -} diff --git a/contrib/tools/python3/src/Python/pyhash.c b/contrib/tools/python3/src/Python/pyhash.c deleted file mode 100644 index f0c82356f1e..00000000000 --- a/contrib/tools/python3/src/Python/pyhash.c +++ /dev/null @@ -1,443 +0,0 @@ -/* Set of hash utility functions to help maintaining the invariant that - if a==b then hash(a)==hash(b) - - All the utility functions (_Py_Hash*()) return "-1" to signify an error. -*/ -#include "Python.h" - -#ifdef __APPLE__ -# include <libkern/OSByteOrder.h> -#elif defined(HAVE_LE64TOH) && defined(HAVE_ENDIAN_H) -# include <endian.h> -#elif defined(HAVE_LE64TOH) && defined(HAVE_SYS_ENDIAN_H) -# include <sys/endian.h> -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -_Py_HashSecret_t _Py_HashSecret = {{0}}; - -#if Py_HASH_ALGORITHM == Py_HASH_EXTERNAL -extern PyHash_FuncDef PyHash_Func; -#else -static PyHash_FuncDef PyHash_Func; -#endif - -/* Count _Py_HashBytes() calls */ -#ifdef Py_HASH_STATS -#define Py_HASH_STATS_MAX 32 -static Py_ssize_t hashstats[Py_HASH_STATS_MAX + 1] = {0}; -#endif - -/* For numeric types, the hash of a number x is based on the reduction - of x modulo the prime P = 2**_PyHASH_BITS - 1. It's designed so that - hash(x) == hash(y) whenever x and y are numerically equal, even if - x and y have different types. - - A quick summary of the hashing strategy: - - (1) First define the 'reduction of x modulo P' for any rational - number x; this is a standard extension of the usual notion of - reduction modulo P for integers. If x == p/q (written in lowest - terms), the reduction is interpreted as the reduction of p times - the inverse of the reduction of q, all modulo P; if q is exactly - divisible by P then define the reduction to be infinity. So we've - got a well-defined map - - reduce : { rational numbers } -> { 0, 1, 2, ..., P-1, infinity }. - - (2) Now for a rational number x, define hash(x) by: - - reduce(x) if x >= 0 - -reduce(-x) if x < 0 - - If the result of the reduction is infinity (this is impossible for - integers, floats and Decimals) then use the predefined hash value - _PyHASH_INF for x >= 0, or -_PyHASH_INF for x < 0, instead. - _PyHASH_INF and -_PyHASH_INF are also used for the - hashes of float and Decimal infinities. - - NaNs hash with a pointer hash. Having distinct hash values prevents - catastrophic pileups from distinct NaN instances which used to always - have the same hash value but would compare unequal. - - A selling point for the above strategy is that it makes it possible - to compute hashes of decimal and binary floating-point numbers - efficiently, even if the exponent of the binary or decimal number - is large. The key point is that - - reduce(x * y) == reduce(x) * reduce(y) (modulo _PyHASH_MODULUS) - - provided that {reduce(x), reduce(y)} != {0, infinity}. The reduction of a - binary or decimal float is never infinity, since the denominator is a power - of 2 (for binary) or a divisor of a power of 10 (for decimal). So we have, - for nonnegative x, - - reduce(x * 2**e) == reduce(x) * reduce(2**e) % _PyHASH_MODULUS - - reduce(x * 10**e) == reduce(x) * reduce(10**e) % _PyHASH_MODULUS - - and reduce(10**e) can be computed efficiently by the usual modular - exponentiation algorithm. For reduce(2**e) it's even better: since - P is of the form 2**n-1, reduce(2**e) is 2**(e mod n), and multiplication - by 2**(e mod n) modulo 2**n-1 just amounts to a rotation of bits. - - */ - -Py_hash_t _Py_HashPointer(const void *); - -Py_hash_t -_Py_HashDouble(PyObject *inst, double v) -{ - int e, sign; - double m; - Py_uhash_t x, y; - - if (!Py_IS_FINITE(v)) { - if (Py_IS_INFINITY(v)) - return v > 0 ? _PyHASH_INF : -_PyHASH_INF; - else - return _Py_HashPointer(inst); - } - - m = frexp(v, &e); - - sign = 1; - if (m < 0) { - sign = -1; - m = -m; - } - - /* process 28 bits at a time; this should work well both for binary - and hexadecimal floating point. */ - x = 0; - while (m) { - x = ((x << 28) & _PyHASH_MODULUS) | x >> (_PyHASH_BITS - 28); - m *= 268435456.0; /* 2**28 */ - e -= 28; - y = (Py_uhash_t)m; /* pull out integer part */ - m -= y; - x += y; - if (x >= _PyHASH_MODULUS) - x -= _PyHASH_MODULUS; - } - - /* adjust for the exponent; first reduce it modulo _PyHASH_BITS */ - e = e >= 0 ? e % _PyHASH_BITS : _PyHASH_BITS-1-((-1-e) % _PyHASH_BITS); - x = ((x << e) & _PyHASH_MODULUS) | x >> (_PyHASH_BITS - e); - - x = x * sign; - if (x == (Py_uhash_t)-1) - x = (Py_uhash_t)-2; - return (Py_hash_t)x; -} - -Py_hash_t -_Py_HashPointerRaw(const void *p) -{ - size_t y = (size_t)p; - /* bottom 3 or 4 bits are likely to be 0; rotate y by 4 to avoid - excessive hash collisions for dicts and sets */ - y = (y >> 4) | (y << (8 * SIZEOF_VOID_P - 4)); - return (Py_hash_t)y; -} - -Py_hash_t -_Py_HashPointer(const void *p) -{ - Py_hash_t x = _Py_HashPointerRaw(p); - if (x == -1) { - x = -2; - } - return x; -} - -Py_hash_t -_Py_HashBytes(const void *src, Py_ssize_t len) -{ - Py_hash_t x; - /* - We make the hash of the empty string be 0, rather than using - (prefix ^ suffix), since this slightly obfuscates the hash secret - */ - if (len == 0) { - return 0; - } - -#ifdef Py_HASH_STATS - hashstats[(len <= Py_HASH_STATS_MAX) ? len : 0]++; -#endif - -#if Py_HASH_CUTOFF > 0 - if (len < Py_HASH_CUTOFF) { - /* Optimize hashing of very small strings with inline DJBX33A. */ - Py_uhash_t hash; - const unsigned char *p = src; - hash = 5381; /* DJBX33A starts with 5381 */ - - switch(len) { - /* ((hash << 5) + hash) + *p == hash * 33 + *p */ - case 7: hash = ((hash << 5) + hash) + *p++; /* fallthrough */ - case 6: hash = ((hash << 5) + hash) + *p++; /* fallthrough */ - case 5: hash = ((hash << 5) + hash) + *p++; /* fallthrough */ - case 4: hash = ((hash << 5) + hash) + *p++; /* fallthrough */ - case 3: hash = ((hash << 5) + hash) + *p++; /* fallthrough */ - case 2: hash = ((hash << 5) + hash) + *p++; /* fallthrough */ - case 1: hash = ((hash << 5) + hash) + *p++; break; - default: - Py_UNREACHABLE(); - } - hash ^= len; - hash ^= (Py_uhash_t) _Py_HashSecret.djbx33a.suffix; - x = (Py_hash_t)hash; - } - else -#endif /* Py_HASH_CUTOFF */ - x = PyHash_Func.hash(src, len); - - if (x == -1) - return -2; - return x; -} - -void -_PyHash_Fini(void) -{ -#ifdef Py_HASH_STATS - fprintf(stderr, "len calls total\n"); - Py_ssize_t total = 0; - for (int i = 1; i <= Py_HASH_STATS_MAX; i++) { - total += hashstats[i]; - fprintf(stderr, "%2i %8zd %8zd\n", i, hashstats[i], total); - } - total += hashstats[0]; - fprintf(stderr, "> %8zd %8zd\n", hashstats[0], total); -#endif -} - -PyHash_FuncDef * -PyHash_GetFuncDef(void) -{ - return &PyHash_Func; -} - -/* Optimized memcpy() for Windows */ -#ifdef _MSC_VER -# if SIZEOF_PY_UHASH_T == 4 -# define PY_UHASH_CPY(dst, src) do { \ - dst[0] = src[0]; dst[1] = src[1]; dst[2] = src[2]; dst[3] = src[3]; \ - } while(0) -# elif SIZEOF_PY_UHASH_T == 8 -# define PY_UHASH_CPY(dst, src) do { \ - dst[0] = src[0]; dst[1] = src[1]; dst[2] = src[2]; dst[3] = src[3]; \ - dst[4] = src[4]; dst[5] = src[5]; dst[6] = src[6]; dst[7] = src[7]; \ - } while(0) -# else -# error SIZEOF_PY_UHASH_T must be 4 or 8 -# endif /* SIZEOF_PY_UHASH_T */ -#else /* not Windows */ -# define PY_UHASH_CPY(dst, src) memcpy(dst, src, SIZEOF_PY_UHASH_T) -#endif /* _MSC_VER */ - - -#if Py_HASH_ALGORITHM == Py_HASH_FNV -/* ************************************************************************** - * Modified Fowler-Noll-Vo (FNV) hash function - */ -static Py_hash_t -fnv(const void *src, Py_ssize_t len) -{ - const unsigned char *p = src; - Py_uhash_t x; - Py_ssize_t remainder, blocks; - union { - Py_uhash_t value; - unsigned char bytes[SIZEOF_PY_UHASH_T]; - } block; - -#ifdef Py_DEBUG - assert(_Py_HashSecret_Initialized); -#endif - remainder = len % SIZEOF_PY_UHASH_T; - if (remainder == 0) { - /* Process at least one block byte by byte to reduce hash collisions - * for strings with common prefixes. */ - remainder = SIZEOF_PY_UHASH_T; - } - blocks = (len - remainder) / SIZEOF_PY_UHASH_T; - - x = (Py_uhash_t) _Py_HashSecret.fnv.prefix; - x ^= (Py_uhash_t) *p << 7; - while (blocks--) { - PY_UHASH_CPY(block.bytes, p); - x = (_PyHASH_MULTIPLIER * x) ^ block.value; - p += SIZEOF_PY_UHASH_T; - } - /* add remainder */ - for (; remainder > 0; remainder--) - x = (_PyHASH_MULTIPLIER * x) ^ (Py_uhash_t) *p++; - x ^= (Py_uhash_t) len; - x ^= (Py_uhash_t) _Py_HashSecret.fnv.suffix; - if (x == (Py_uhash_t) -1) { - x = (Py_uhash_t) -2; - } - return x; -} - -static PyHash_FuncDef PyHash_Func = {fnv, "fnv", 8 * SIZEOF_PY_HASH_T, - 16 * SIZEOF_PY_HASH_T}; - -#endif /* Py_HASH_ALGORITHM == Py_HASH_FNV */ - - -/* ************************************************************************** - <MIT License> - Copyright (c) 2013 Marek Majkowski <[email protected]> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. - </MIT License> - - Original location: - https://github.com/majek/csiphash/ - - Solution inspired by code from: - Samuel Neves (supercop/crypto_auth/siphash24/little) - djb (supercop/crypto_auth/siphash24/little2) - Jean-Philippe Aumasson (https://131002.net/siphash/siphash24.c) - - Modified for Python by Christian Heimes: - - C89 / MSVC compatibility - - _rotl64() on Windows - - letoh64() fallback -*/ - -/* byte swap little endian to host endian - * Endian conversion not only ensures that the hash function returns the same - * value on all platforms. It is also required to for a good dispersion of - * the hash values' least significant bits. - */ -#if PY_LITTLE_ENDIAN -# define _le64toh(x) ((uint64_t)(x)) -#elif defined(__APPLE__) -# define _le64toh(x) OSSwapLittleToHostInt64(x) -#elif defined(HAVE_LETOH64) -# define _le64toh(x) le64toh(x) -#else -# define _le64toh(x) (((uint64_t)(x) << 56) | \ - (((uint64_t)(x) << 40) & 0xff000000000000ULL) | \ - (((uint64_t)(x) << 24) & 0xff0000000000ULL) | \ - (((uint64_t)(x) << 8) & 0xff00000000ULL) | \ - (((uint64_t)(x) >> 8) & 0xff000000ULL) | \ - (((uint64_t)(x) >> 24) & 0xff0000ULL) | \ - (((uint64_t)(x) >> 40) & 0xff00ULL) | \ - ((uint64_t)(x) >> 56)) -#endif - - -#ifdef _MSC_VER -# define ROTATE(x, b) _rotl64(x, b) -#else -# define ROTATE(x, b) (uint64_t)( ((x) << (b)) | ( (x) >> (64 - (b))) ) -#endif - -#define HALF_ROUND(a,b,c,d,s,t) \ - a += b; c += d; \ - b = ROTATE(b, s) ^ a; \ - d = ROTATE(d, t) ^ c; \ - a = ROTATE(a, 32); - -#define DOUBLE_ROUND(v0,v1,v2,v3) \ - HALF_ROUND(v0,v1,v2,v3,13,16); \ - HALF_ROUND(v2,v1,v0,v3,17,21); \ - HALF_ROUND(v0,v1,v2,v3,13,16); \ - HALF_ROUND(v2,v1,v0,v3,17,21); - - -static uint64_t -siphash24(uint64_t k0, uint64_t k1, const void *src, Py_ssize_t src_sz) { - uint64_t b = (uint64_t)src_sz << 56; - const uint8_t *in = (const uint8_t*)src; - - uint64_t v0 = k0 ^ 0x736f6d6570736575ULL; - uint64_t v1 = k1 ^ 0x646f72616e646f6dULL; - uint64_t v2 = k0 ^ 0x6c7967656e657261ULL; - uint64_t v3 = k1 ^ 0x7465646279746573ULL; - - uint64_t t; - uint8_t *pt; - - while (src_sz >= 8) { - uint64_t mi; - memcpy(&mi, in, sizeof(mi)); - mi = _le64toh(mi); - in += sizeof(mi); - src_sz -= sizeof(mi); - v3 ^= mi; - DOUBLE_ROUND(v0,v1,v2,v3); - v0 ^= mi; - } - - t = 0; - pt = (uint8_t *)&t; - switch (src_sz) { - case 7: pt[6] = in[6]; /* fall through */ - case 6: pt[5] = in[5]; /* fall through */ - case 5: pt[4] = in[4]; /* fall through */ - case 4: memcpy(pt, in, sizeof(uint32_t)); break; - case 3: pt[2] = in[2]; /* fall through */ - case 2: pt[1] = in[1]; /* fall through */ - case 1: pt[0] = in[0]; /* fall through */ - } - b |= _le64toh(t); - - v3 ^= b; - DOUBLE_ROUND(v0,v1,v2,v3); - v0 ^= b; - v2 ^= 0xff; - DOUBLE_ROUND(v0,v1,v2,v3); - DOUBLE_ROUND(v0,v1,v2,v3); - - /* modified */ - t = (v0 ^ v1) ^ (v2 ^ v3); - return t; -} - -uint64_t -_Py_KeyedHash(uint64_t key, const void *src, Py_ssize_t src_sz) -{ - return siphash24(key, 0, src, src_sz); -} - - -#if Py_HASH_ALGORITHM == Py_HASH_SIPHASH24 -static Py_hash_t -pysiphash(const void *src, Py_ssize_t src_sz) { - return (Py_hash_t)siphash24( - _le64toh(_Py_HashSecret.siphash.k0), _le64toh(_Py_HashSecret.siphash.k1), - src, src_sz); -} - -static PyHash_FuncDef PyHash_Func = {pysiphash, "siphash24", 64, 128}; -#endif - -#ifdef __cplusplus -} -#endif diff --git a/contrib/tools/python3/src/Python/pylifecycle.c b/contrib/tools/python3/src/Python/pylifecycle.c deleted file mode 100644 index 0d534fcf685..00000000000 --- a/contrib/tools/python3/src/Python/pylifecycle.c +++ /dev/null @@ -1,2979 +0,0 @@ -/* Python interpreter top-level routines, including init/exit */ - -#include "Python.h" - -#include "pycore_ceval.h" // _PyEval_FiniGIL() -#include "pycore_context.h" // _PyContext_Init() -#include "pycore_fileutils.h" // _Py_ResetForceASCII() -#include "pycore_import.h" // _PyImport_BootstrapImp() -#include "pycore_initconfig.h" // _PyStatus_OK() -#include "pycore_object.h" // _PyDebug_PrintTotalRefs() -#include "pycore_pathconfig.h" // _PyConfig_WritePathConfig() -#include "pycore_pyerrors.h" // _PyErr_Occurred() -#include "pycore_pylifecycle.h" // _PyErr_Print() -#include "pycore_pystate.h" // _PyThreadState_GET() -#include "pycore_sysmodule.h" // _PySys_ClearAuditHooks() -#include "pycore_traceback.h" // _Py_DumpTracebackThreads() - -#include <locale.h> // setlocale() - -#if defined(__APPLE__) -#include <mach-o/loader.h> -#endif - -#ifdef HAVE_SIGNAL_H -# include <signal.h> // SIG_IGN -#endif - -#ifdef HAVE_LANGINFO_H -# include <langinfo.h> // nl_langinfo(CODESET) -#endif - -#ifdef MS_WINDOWS -# undef BYTE -# include "windows.h" - - extern PyTypeObject PyWindowsConsoleIO_Type; -# define PyWindowsConsoleIO_Check(op) \ - (PyObject_TypeCheck((op), &PyWindowsConsoleIO_Type)) -#endif - -#define PUTS(fd, str) _Py_write_noraise(fd, str, (int)strlen(str)) - - -_Py_IDENTIFIER(flush); -_Py_IDENTIFIER(name); -_Py_IDENTIFIER(stdin); -_Py_IDENTIFIER(stdout); -_Py_IDENTIFIER(stderr); -_Py_IDENTIFIER(threading); - -#ifdef __cplusplus -extern "C" { -#endif - - -/* Forward declarations */ -static PyStatus add_main_module(PyInterpreterState *interp); -static PyStatus init_import_site(void); -static PyStatus init_set_builtins_open(void); -static PyStatus init_sys_streams(PyThreadState *tstate); -static void wait_for_thread_shutdown(PyThreadState *tstate); -static void call_ll_exitfuncs(_PyRuntimeState *runtime); - -int _Py_UnhandledKeyboardInterrupt = 0; - -/* The following places the `_PyRuntime` structure in a location that can be - * found without any external information. This is meant to ease access to the - * interpreter state for various runtime debugging tools, but is *not* an - * officially supported feature */ - -#if defined(MS_WINDOWS) - -#pragma section("PyRuntime", read, write) -__declspec(allocate("PyRuntime")) - -#elif defined(__APPLE__) - -__attribute__(( - section(SEG_DATA ",PyRuntime") -)) - -#endif - -_PyRuntimeState _PyRuntime -#if defined(__linux__) && (defined(__GNUC__) || defined(__clang__)) -__attribute__ ((section (".PyRuntime"))) -#endif -= _PyRuntimeState_INIT; -static int runtime_initialized = 0; - -PyStatus -_PyRuntime_Initialize(void) -{ - /* XXX We only initialize once in the process, which aligns with - the static initialization of the former globals now found in - _PyRuntime. However, _PyRuntime *should* be initialized with - every Py_Initialize() call, but doing so breaks the runtime. - This is because the runtime state is not properly finalized - currently. */ - if (runtime_initialized) { - return _PyStatus_OK(); - } - runtime_initialized = 1; - - return _PyRuntimeState_Init(&_PyRuntime); -} - -void -_PyRuntime_Finalize(void) -{ - _PyRuntimeState_Fini(&_PyRuntime); - runtime_initialized = 0; -} - -int -_Py_IsFinalizing(void) -{ - return _PyRuntimeState_GetFinalizing(&_PyRuntime) != NULL; -} - -/* Hack to force loading of object files */ -int (*_PyOS_mystrnicmp_hack)(const char *, const char *, Py_ssize_t) = \ - PyOS_mystrnicmp; /* Python/pystrcmp.o */ - - -/* APIs to access the initialization flags - * - * Can be called prior to Py_Initialize. - */ - -int -_Py_IsCoreInitialized(void) -{ - return _PyRuntime.core_initialized; -} - -int -Py_IsInitialized(void) -{ - return _PyRuntime.initialized; -} - - -/* Global initializations. Can be undone by Py_FinalizeEx(). Don't - call this twice without an intervening Py_FinalizeEx() call. When - initializations fail, a fatal error is issued and the function does - not return. On return, the first thread and interpreter state have - been created. - - Locking: you must hold the interpreter lock while calling this. - (If the lock has not yet been initialized, that's equivalent to - having the lock, but you cannot use multiple threads.) - -*/ -static int -init_importlib(PyThreadState *tstate, PyObject *sysmod) -{ - assert(!_PyErr_Occurred(tstate)); - - PyInterpreterState *interp = tstate->interp; - int verbose = _PyInterpreterState_GetConfig(interp)->verbose; - - // Import _importlib through its frozen version, _frozen_importlib. - if (verbose) { - PySys_FormatStderr("import _frozen_importlib # frozen\n"); - } - if (PyImport_ImportFrozenModule("_frozen_importlib") <= 0) { - return -1; - } - PyObject *importlib = PyImport_AddModule("_frozen_importlib"); // borrowed - if (importlib == NULL) { - return -1; - } - interp->importlib = Py_NewRef(importlib); - - // Import the _imp module - if (verbose) { - PySys_FormatStderr("import _imp # builtin\n"); - } - PyObject *imp_mod = _PyImport_BootstrapImp(tstate); - if (imp_mod == NULL) { - return -1; - } - if (_PyImport_SetModuleString("_imp", imp_mod) < 0) { - Py_DECREF(imp_mod); - return -1; - } - - // Install importlib as the implementation of import - PyObject *value = PyObject_CallMethod(importlib, "_install", - "OO", sysmod, imp_mod); - Py_DECREF(imp_mod); - if (value == NULL) { - return -1; - } - Py_DECREF(value); - - assert(!_PyErr_Occurred(tstate)); - return 0; -} - - -static PyStatus -init_importlib_external(PyThreadState *tstate) -{ - PyObject *value; - value = PyObject_CallMethod(tstate->interp->importlib, - "_install_external_importers", ""); - if (value == NULL) { - _PyErr_Print(tstate); - return _PyStatus_ERR("external importer setup failed"); - } - Py_DECREF(value); - - value = PyImport_ImportModule("__res"); - if (value == NULL) { - PyErr_Print(); - return _PyStatus_ERR("can't import __res"); - } - Py_DECREF(value); - - return _PyImportZip_Init(tstate); -} - -/* Helper functions to better handle the legacy C locale - * - * The legacy C locale assumes ASCII as the default text encoding, which - * causes problems not only for the CPython runtime, but also other - * components like GNU readline. - * - * Accordingly, when the CLI detects it, it attempts to coerce it to a - * more capable UTF-8 based alternative as follows: - * - * if (_Py_LegacyLocaleDetected()) { - * _Py_CoerceLegacyLocale(); - * } - * - * See the documentation of the PYTHONCOERCECLOCALE setting for more details. - * - * Locale coercion also impacts the default error handler for the standard - * streams: while the usual default is "strict", the default for the legacy - * C locale and for any of the coercion target locales is "surrogateescape". - */ - -int -_Py_LegacyLocaleDetected(int warn) -{ -#ifndef MS_WINDOWS - if (!warn) { - const char *locale_override = getenv("LC_ALL"); - if (locale_override != NULL && *locale_override != '\0') { - /* Don't coerce C locale if the LC_ALL environment variable - is set */ - return 0; - } - } - - /* On non-Windows systems, the C locale is considered a legacy locale */ - /* XXX (ncoghlan): some platforms (notably Mac OS X) don't appear to treat - * the POSIX locale as a simple alias for the C locale, so - * we may also want to check for that explicitly. - */ - const char *ctype_loc = setlocale(LC_CTYPE, NULL); - return ctype_loc != NULL && strcmp(ctype_loc, "C") == 0; -#else - /* Windows uses code pages instead of locales, so no locale is legacy */ - return 0; -#endif -} - -#ifndef MS_WINDOWS -static const char *_C_LOCALE_WARNING = - "Python runtime initialized with LC_CTYPE=C (a locale with default ASCII " - "encoding), which may cause Unicode compatibility problems. Using C.UTF-8, " - "C.utf8, or UTF-8 (if available) as alternative Unicode-compatible " - "locales is recommended.\n"; - -static void -emit_stderr_warning_for_legacy_locale(_PyRuntimeState *runtime) -{ - const PyPreConfig *preconfig = &runtime->preconfig; - if (preconfig->coerce_c_locale_warn && _Py_LegacyLocaleDetected(1)) { - PySys_FormatStderr("%s", _C_LOCALE_WARNING); - } -} -#endif /* !defined(MS_WINDOWS) */ - -typedef struct _CandidateLocale { - const char *locale_name; /* The locale to try as a coercion target */ -} _LocaleCoercionTarget; - -static _LocaleCoercionTarget _TARGET_LOCALES[] = { - {"C.UTF-8"}, - {"C.utf8"}, - {"UTF-8"}, - {NULL} -}; - - -int -_Py_IsLocaleCoercionTarget(const char *ctype_loc) -{ - const _LocaleCoercionTarget *target = NULL; - for (target = _TARGET_LOCALES; target->locale_name; target++) { - if (strcmp(ctype_loc, target->locale_name) == 0) { - return 1; - } - } - return 0; -} - - -#ifdef PY_COERCE_C_LOCALE -static const char C_LOCALE_COERCION_WARNING[] = - "Python detected LC_CTYPE=C: LC_CTYPE coerced to %.20s (set another locale " - "or PYTHONCOERCECLOCALE=0 to disable this locale coercion behavior).\n"; - -static int -_coerce_default_locale_settings(int warn, const _LocaleCoercionTarget *target) -{ - const char *newloc = target->locale_name; - - /* Reset locale back to currently configured defaults */ - _Py_SetLocaleFromEnv(LC_ALL); - - /* Set the relevant locale environment variable */ - if (setenv("LC_CTYPE", newloc, 1)) { - fprintf(stderr, - "Error setting LC_CTYPE, skipping C locale coercion\n"); - return 0; - } - if (warn) { - fprintf(stderr, C_LOCALE_COERCION_WARNING, newloc); - } - - /* Reconfigure with the overridden environment variables */ - _Py_SetLocaleFromEnv(LC_ALL); - return 1; -} -#endif - -int -_Py_CoerceLegacyLocale(int warn) -{ - int coerced = 0; -#ifdef PY_COERCE_C_LOCALE - char *oldloc = NULL; - - oldloc = _PyMem_RawStrdup(setlocale(LC_CTYPE, NULL)); - if (oldloc == NULL) { - return coerced; - } - - const char *locale_override = getenv("LC_ALL"); - if (locale_override == NULL || *locale_override == '\0') { - /* LC_ALL is also not set (or is set to an empty string) */ - const _LocaleCoercionTarget *target = NULL; - for (target = _TARGET_LOCALES; target->locale_name; target++) { - const char *new_locale = setlocale(LC_CTYPE, - target->locale_name); - if (new_locale != NULL) { -#if !defined(_Py_FORCE_UTF8_LOCALE) && defined(HAVE_LANGINFO_H) && defined(CODESET) - /* Also ensure that nl_langinfo works in this locale */ - char *codeset = nl_langinfo(CODESET); - if (!codeset || *codeset == '\0') { - /* CODESET is not set or empty, so skip coercion */ - new_locale = NULL; - _Py_SetLocaleFromEnv(LC_CTYPE); - continue; - } -#endif - /* Successfully configured locale, so make it the default */ - coerced = _coerce_default_locale_settings(warn, target); - goto done; - } - } - } - /* No C locale warning here, as Py_Initialize will emit one later */ - - setlocale(LC_CTYPE, oldloc); - -done: - PyMem_RawFree(oldloc); -#endif - return coerced; -} - -/* _Py_SetLocaleFromEnv() is a wrapper around setlocale(category, "") to - * isolate the idiosyncrasies of different libc implementations. It reads the - * appropriate environment variable and uses its value to select the locale for - * 'category'. */ -char * -_Py_SetLocaleFromEnv(int category) -{ - char *res; -#ifdef __ANDROID__ - const char *locale; - const char **pvar; -#ifdef PY_COERCE_C_LOCALE - const char *coerce_c_locale; -#endif - const char *utf8_locale = "C.UTF-8"; - const char *env_var_set[] = { - "LC_ALL", - "LC_CTYPE", - "LANG", - NULL, - }; - - /* Android setlocale(category, "") doesn't check the environment variables - * and incorrectly sets the "C" locale at API 24 and older APIs. We only - * check the environment variables listed in env_var_set. */ - for (pvar=env_var_set; *pvar; pvar++) { - locale = getenv(*pvar); - if (locale != NULL && *locale != '\0') { - if (strcmp(locale, utf8_locale) == 0 || - strcmp(locale, "en_US.UTF-8") == 0) { - return setlocale(category, utf8_locale); - } - return setlocale(category, "C"); - } - } - - /* Android uses UTF-8, so explicitly set the locale to C.UTF-8 if none of - * LC_ALL, LC_CTYPE, or LANG is set to a non-empty string. - * Quote from POSIX section "8.2 Internationalization Variables": - * "4. If the LANG environment variable is not set or is set to the empty - * string, the implementation-defined default locale shall be used." */ - -#ifdef PY_COERCE_C_LOCALE - coerce_c_locale = getenv("PYTHONCOERCECLOCALE"); - if (coerce_c_locale == NULL || strcmp(coerce_c_locale, "0") != 0) { - /* Some other ported code may check the environment variables (e.g. in - * extension modules), so we make sure that they match the locale - * configuration */ - if (setenv("LC_CTYPE", utf8_locale, 1)) { - fprintf(stderr, "Warning: failed setting the LC_CTYPE " - "environment variable to %s\n", utf8_locale); - } - } -#endif - res = setlocale(category, utf8_locale); -#else /* !defined(__ANDROID__) */ - res = setlocale(category, ""); -#endif - _Py_ResetForceASCII(); - return res; -} - - -static int -interpreter_update_config(PyThreadState *tstate, int only_update_path_config) -{ - const PyConfig *config = &tstate->interp->config; - - if (!only_update_path_config) { - PyStatus status = _PyConfig_Write(config, tstate->interp->runtime); - if (_PyStatus_EXCEPTION(status)) { - _PyErr_SetFromPyStatus(status); - return -1; - } - } - - if (_Py_IsMainInterpreter(tstate->interp)) { - PyStatus status = _PyConfig_WritePathConfig(config); - if (_PyStatus_EXCEPTION(status)) { - _PyErr_SetFromPyStatus(status); - return -1; - } - } - - // Update the sys module for the new configuration - if (_PySys_UpdateConfig(tstate) < 0) { - return -1; - } - return 0; -} - - -int -_PyInterpreterState_SetConfig(const PyConfig *src_config) -{ - PyThreadState *tstate = PyThreadState_Get(); - int res = -1; - - PyConfig config; - PyConfig_InitPythonConfig(&config); - PyStatus status = _PyConfig_Copy(&config, src_config); - if (_PyStatus_EXCEPTION(status)) { - _PyErr_SetFromPyStatus(status); - goto done; - } - - status = PyConfig_Read(&config); - if (_PyStatus_EXCEPTION(status)) { - _PyErr_SetFromPyStatus(status); - goto done; - } - - status = _PyConfig_Copy(&tstate->interp->config, &config); - if (_PyStatus_EXCEPTION(status)) { - _PyErr_SetFromPyStatus(status); - goto done; - } - - res = interpreter_update_config(tstate, 0); - -done: - PyConfig_Clear(&config); - return res; -} - - -/* Global initializations. Can be undone by Py_Finalize(). Don't - call this twice without an intervening Py_Finalize() call. - - Every call to Py_InitializeFromConfig, Py_Initialize or Py_InitializeEx - must have a corresponding call to Py_Finalize. - - Locking: you must hold the interpreter lock while calling these APIs. - (If the lock has not yet been initialized, that's equivalent to - having the lock, but you cannot use multiple threads.) - -*/ - -static PyStatus -pyinit_core_reconfigure(_PyRuntimeState *runtime, - PyThreadState **tstate_p, - const PyConfig *config) -{ - PyStatus status; - PyThreadState *tstate = _PyThreadState_GET(); - if (!tstate) { - return _PyStatus_ERR("failed to read thread state"); - } - *tstate_p = tstate; - - PyInterpreterState *interp = tstate->interp; - if (interp == NULL) { - return _PyStatus_ERR("can't make main interpreter"); - } - - status = _PyConfig_Write(config, runtime); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - status = _PyConfig_Copy(&interp->config, config); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - config = _PyInterpreterState_GetConfig(interp); - - if (config->_install_importlib) { - status = _PyConfig_WritePathConfig(config); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - } - return _PyStatus_OK(); -} - - -static PyStatus -pycore_init_runtime(_PyRuntimeState *runtime, - const PyConfig *config) -{ - if (runtime->initialized) { - return _PyStatus_ERR("main interpreter already initialized"); - } - - PyStatus status = _PyConfig_Write(config, runtime); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - /* Py_Finalize leaves _Py_Finalizing set in order to help daemon - * threads behave a little more gracefully at interpreter shutdown. - * We clobber it here so the new interpreter can start with a clean - * slate. - * - * However, this may still lead to misbehaviour if there are daemon - * threads still hanging around from a previous Py_Initialize/Finalize - * pair :( - */ - _PyRuntimeState_SetFinalizing(runtime, NULL); - - status = _Py_HashRandomization_Init(config); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - status = _PyInterpreterState_Enable(runtime); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - return _PyStatus_OK(); -} - - -static PyStatus -init_interp_create_gil(PyThreadState *tstate) -{ - PyStatus status; - - /* finalize_interp_delete() comment explains why _PyEval_FiniGIL() is - only called here. */ - _PyEval_FiniGIL(tstate->interp); - - /* Auto-thread-state API */ - status = _PyGILState_SetTstate(tstate); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - /* Create the GIL and take it */ - status = _PyEval_InitGIL(tstate); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - return _PyStatus_OK(); -} - - -static PyStatus -pycore_create_interpreter(_PyRuntimeState *runtime, - const PyConfig *config, - PyThreadState **tstate_p) -{ - /* Auto-thread-state API */ - PyStatus status = _PyGILState_Init(runtime); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - PyInterpreterState *interp = PyInterpreterState_New(); - if (interp == NULL) { - return _PyStatus_ERR("can't make main interpreter"); - } - assert(_Py_IsMainInterpreter(interp)); - - status = _PyConfig_Copy(&interp->config, config); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - PyThreadState *tstate = PyThreadState_New(interp); - if (tstate == NULL) { - return _PyStatus_ERR("can't make first thread"); - } - (void) PyThreadState_Swap(tstate); - - status = init_interp_create_gil(tstate); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - *tstate_p = tstate; - return _PyStatus_OK(); -} - - -static PyStatus -pycore_init_singletons(PyInterpreterState *interp) -{ - PyStatus status; - - if (_PyLong_Init(interp) < 0) { - return _PyStatus_ERR("can't init longs"); - } - - if (_Py_IsMainInterpreter(interp)) { - _PyFloat_Init(); - } - - status = _PyBytes_Init(interp); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - status = _PyUnicode_Init(interp); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - status = _PyTuple_Init(interp); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - return _PyStatus_OK(); -} - - -static PyStatus -pycore_init_types(PyInterpreterState *interp) -{ - PyStatus status; - int is_main_interp = _Py_IsMainInterpreter(interp); - - if (is_main_interp) { - if (_PyStructSequence_Init() < 0) { - return _PyStatus_ERR("can't initialize structseq"); - } - - status = _PyTypes_Init(); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - if (_PyLong_InitTypes() < 0) { - return _PyStatus_ERR("can't init int type"); - } - - status = _PyUnicode_InitTypes(); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - } - - if (is_main_interp) { - if (_PyFloat_InitTypes() < 0) { - return _PyStatus_ERR("can't init float"); - } - } - - status = _PyExc_Init(interp); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - status = _PyErr_InitTypes(); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - if (is_main_interp) { - if (!_PyContext_Init()) { - return _PyStatus_ERR("can't init context"); - } - } - - return _PyStatus_OK(); -} - - -static PyStatus -pycore_init_builtins(PyThreadState *tstate) -{ - PyInterpreterState *interp = tstate->interp; - - PyObject *bimod = _PyBuiltin_Init(interp); - if (bimod == NULL) { - goto error; - } - - if (_PyImport_FixupBuiltin(bimod, "builtins", interp->modules) < 0) { - goto error; - } - - PyObject *builtins_dict = PyModule_GetDict(bimod); - if (builtins_dict == NULL) { - goto error; - } - Py_INCREF(builtins_dict); - interp->builtins = builtins_dict; - - PyStatus status = _PyBuiltins_AddExceptions(bimod); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - interp->builtins_copy = PyDict_Copy(interp->builtins); - if (interp->builtins_copy == NULL) { - goto error; - } - Py_DECREF(bimod); - - // Get the __import__ function - PyObject *import_func = _PyDict_GetItemStringWithError(interp->builtins, - "__import__"); - if (import_func == NULL) { - goto error; - } - interp->import_func = Py_NewRef(import_func); - - assert(!_PyErr_Occurred(tstate)); - return _PyStatus_OK(); - -error: - Py_XDECREF(bimod); - return _PyStatus_ERR("can't initialize builtins module"); -} - - -static PyStatus -pycore_interp_init(PyThreadState *tstate) -{ - PyInterpreterState *interp = tstate->interp; - PyStatus status; - PyObject *sysmod = NULL; - - // Create singletons before the first PyType_Ready() call, since - // PyType_Ready() uses singletons like the Unicode empty string (tp_doc) - // and the empty tuple singletons (tp_bases). - status = pycore_init_singletons(interp); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - // The GC must be initialized before the first GC collection. - status = _PyGC_Init(interp); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - status = pycore_init_types(interp); - if (_PyStatus_EXCEPTION(status)) { - goto done; - } - - if (_PyWarnings_InitState(interp) < 0) { - return _PyStatus_ERR("can't initialize warnings"); - } - - status = _PyAtExit_Init(interp); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - status = _PySys_Create(tstate, &sysmod); - if (_PyStatus_EXCEPTION(status)) { - goto done; - } - - status = pycore_init_builtins(tstate); - if (_PyStatus_EXCEPTION(status)) { - goto done; - } - - const PyConfig *config = _PyInterpreterState_GetConfig(interp); - if (config->_install_importlib) { - /* This call sets up builtin and frozen import support */ - if (init_importlib(tstate, sysmod) < 0) { - return _PyStatus_ERR("failed to initialize importlib"); - } - } - -done: - /* sys.modules['sys'] contains a strong reference to the module */ - Py_XDECREF(sysmod); - return status; -} - - -static PyStatus -pyinit_config(_PyRuntimeState *runtime, - PyThreadState **tstate_p, - const PyConfig *config) -{ - PyStatus status = pycore_init_runtime(runtime, config); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - PyThreadState *tstate; - status = pycore_create_interpreter(runtime, config, &tstate); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - *tstate_p = tstate; - - status = pycore_interp_init(tstate); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - /* Only when we get here is the runtime core fully initialized */ - runtime->core_initialized = 1; - return _PyStatus_OK(); -} - - -PyStatus -_Py_PreInitializeFromPyArgv(const PyPreConfig *src_config, const _PyArgv *args) -{ - PyStatus status; - - if (src_config == NULL) { - return _PyStatus_ERR("preinitialization config is NULL"); - } - - status = _PyRuntime_Initialize(); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - _PyRuntimeState *runtime = &_PyRuntime; - - if (runtime->preinitialized) { - /* If it's already configured: ignored the new configuration */ - return _PyStatus_OK(); - } - - /* Note: preinitialized remains 1 on error, it is only set to 0 - at exit on success. */ - runtime->preinitializing = 1; - - PyPreConfig config; - - status = _PyPreConfig_InitFromPreConfig(&config, src_config); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - status = _PyPreConfig_Read(&config, args); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - status = _PyPreConfig_Write(&config); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - runtime->preinitializing = 0; - runtime->preinitialized = 1; - return _PyStatus_OK(); -} - - -PyStatus -Py_PreInitializeFromBytesArgs(const PyPreConfig *src_config, Py_ssize_t argc, char **argv) -{ - _PyArgv args = {.use_bytes_argv = 1, .argc = argc, .bytes_argv = argv}; - return _Py_PreInitializeFromPyArgv(src_config, &args); -} - - -PyStatus -Py_PreInitializeFromArgs(const PyPreConfig *src_config, Py_ssize_t argc, wchar_t **argv) -{ - _PyArgv args = {.use_bytes_argv = 0, .argc = argc, .wchar_argv = argv}; - return _Py_PreInitializeFromPyArgv(src_config, &args); -} - - -PyStatus -Py_PreInitialize(const PyPreConfig *src_config) -{ - return _Py_PreInitializeFromPyArgv(src_config, NULL); -} - - -PyStatus -_Py_PreInitializeFromConfig(const PyConfig *config, - const _PyArgv *args) -{ - assert(config != NULL); - - PyStatus status = _PyRuntime_Initialize(); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - _PyRuntimeState *runtime = &_PyRuntime; - - if (runtime->preinitialized) { - /* Already initialized: do nothing */ - return _PyStatus_OK(); - } - - PyPreConfig preconfig; - - _PyPreConfig_InitFromConfig(&preconfig, config); - - if (!config->parse_argv) { - return Py_PreInitialize(&preconfig); - } - else if (args == NULL) { - _PyArgv config_args = { - .use_bytes_argv = 0, - .argc = config->argv.length, - .wchar_argv = config->argv.items}; - return _Py_PreInitializeFromPyArgv(&preconfig, &config_args); - } - else { - return _Py_PreInitializeFromPyArgv(&preconfig, args); - } -} - - -/* Begin interpreter initialization - * - * On return, the first thread and interpreter state have been created, - * but the compiler, signal handling, multithreading and - * multiple interpreter support, and codec infrastructure are not yet - * available. - * - * The import system will support builtin and frozen modules only. - * The only supported io is writing to sys.stderr - * - * If any operation invoked by this function fails, a fatal error is - * issued and the function does not return. - * - * Any code invoked from this function should *not* assume it has access - * to the Python C API (unless the API is explicitly listed as being - * safe to call without calling Py_Initialize first) - */ -static PyStatus -pyinit_core(_PyRuntimeState *runtime, - const PyConfig *src_config, - PyThreadState **tstate_p) -{ - PyStatus status; - - status = _Py_PreInitializeFromConfig(src_config, NULL); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - PyConfig config; - PyConfig_InitPythonConfig(&config); - - status = _PyConfig_Copy(&config, src_config); - if (_PyStatus_EXCEPTION(status)) { - goto done; - } - - // Read the configuration, but don't compute the path configuration - // (it is computed in the main init). - status = _PyConfig_Read(&config, 0); - if (_PyStatus_EXCEPTION(status)) { - goto done; - } - - if (!runtime->core_initialized) { - status = pyinit_config(runtime, tstate_p, &config); - } - else { - status = pyinit_core_reconfigure(runtime, tstate_p, &config); - } - if (_PyStatus_EXCEPTION(status)) { - goto done; - } - -done: - PyConfig_Clear(&config); - return status; -} - - -/* Py_Initialize() has already been called: update the main interpreter - configuration. Example of bpo-34008: Py_Main() called after - Py_Initialize(). */ -static PyStatus -pyinit_main_reconfigure(PyThreadState *tstate) -{ - if (interpreter_update_config(tstate, 0) < 0) { - return _PyStatus_ERR("fail to reconfigure Python"); - } - return _PyStatus_OK(); -} - - -static PyStatus -init_interp_main(PyThreadState *tstate) -{ - extern void _PyThread_debug_deprecation(void); - - assert(!_PyErr_Occurred(tstate)); - - PyStatus status; - int is_main_interp = _Py_IsMainInterpreter(tstate->interp); - PyInterpreterState *interp = tstate->interp; - const PyConfig *config = _PyInterpreterState_GetConfig(interp); - - if (!config->_install_importlib) { - /* Special mode for freeze_importlib: run with no import system - * - * This means anything which needs support from extension modules - * or pure Python code in the standard library won't work. - */ - if (is_main_interp) { - interp->runtime->initialized = 1; - } - return _PyStatus_OK(); - } - - // Compute the path configuration - status = _PyConfig_InitPathConfig(&interp->config, 1); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - if (interpreter_update_config(tstate, 1) < 0) { - return _PyStatus_ERR("failed to update the Python config"); - } - - status = init_importlib_external(tstate); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - if (is_main_interp) { - /* initialize the faulthandler module */ - status = _PyFaulthandler_Init(config->faulthandler); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - } - - status = _PyUnicode_InitEncodings(tstate); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - if (is_main_interp) { - if (_PySignal_Init(config->install_signal_handlers) < 0) { - return _PyStatus_ERR("can't initialize signals"); - } - - if (_PyTraceMalloc_Init(config->tracemalloc) < 0) { - return _PyStatus_ERR("can't initialize tracemalloc"); - } - } - - status = init_sys_streams(tstate); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - status = init_set_builtins_open(); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - status = add_main_module(interp); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - if (is_main_interp) { - /* Initialize warnings. */ - PyObject *warnoptions = PySys_GetObject("warnoptions"); - if (warnoptions != NULL && PyList_Size(warnoptions) > 0) - { - PyObject *warnings_module = PyImport_ImportModule("warnings"); - if (warnings_module == NULL) { - fprintf(stderr, "'import warnings' failed; traceback:\n"); - _PyErr_Print(tstate); - } - Py_XDECREF(warnings_module); - } - - interp->runtime->initialized = 1; - } - - if (config->site_import) { - status = init_import_site(); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - } - - if (is_main_interp) { -#ifndef MS_WINDOWS - emit_stderr_warning_for_legacy_locale(interp->runtime); -#endif - } - - // Warn about PYTHONTHREADDEBUG deprecation - _PyThread_debug_deprecation(); - - assert(!_PyErr_Occurred(tstate)); - - return _PyStatus_OK(); -} - - -/* Update interpreter state based on supplied configuration settings - * - * After calling this function, most of the restrictions on the interpreter - * are lifted. The only remaining incomplete settings are those related - * to the main module (sys.argv[0], __main__ metadata) - * - * Calling this when the interpreter is not initializing, is already - * initialized or without a valid current thread state is a fatal error. - * Other errors should be reported as normal Python exceptions with a - * non-zero return code. - */ -static PyStatus -pyinit_main(PyThreadState *tstate) -{ - PyInterpreterState *interp = tstate->interp; - if (!interp->runtime->core_initialized) { - return _PyStatus_ERR("runtime core not initialized"); - } - - if (interp->runtime->initialized) { - return pyinit_main_reconfigure(tstate); - } - - PyStatus status = init_interp_main(tstate); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - return _PyStatus_OK(); -} - - -PyStatus -Py_InitializeFromConfig(const PyConfig *config) -{ - if (config == NULL) { - return _PyStatus_ERR("initialization config is NULL"); - } - - PyStatus status; - - status = _PyRuntime_Initialize(); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - _PyRuntimeState *runtime = &_PyRuntime; - - PyThreadState *tstate = NULL; - status = pyinit_core(runtime, config, &tstate); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - config = _PyInterpreterState_GetConfig(tstate->interp); - - if (config->_init_main) { - status = pyinit_main(tstate); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - } - - return _PyStatus_OK(); -} - - -void -Py_InitializeEx(int install_sigs) -{ - PyStatus status; - - status = _PyRuntime_Initialize(); - if (_PyStatus_EXCEPTION(status)) { - Py_ExitStatusException(status); - } - _PyRuntimeState *runtime = &_PyRuntime; - - if (runtime->initialized) { - /* bpo-33932: Calling Py_Initialize() twice does nothing. */ - return; - } - - PyConfig config; - _PyConfig_InitCompatConfig(&config); - - config.install_signal_handlers = install_sigs; - - status = Py_InitializeFromConfig(&config); - if (_PyStatus_EXCEPTION(status)) { - Py_ExitStatusException(status); - } -} - -void -Py_Initialize(void) -{ - Py_InitializeEx(1); -} - - -PyStatus -_Py_InitializeMain(void) -{ - PyStatus status = _PyRuntime_Initialize(); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - _PyRuntimeState *runtime = &_PyRuntime; - PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); - return pyinit_main(tstate); -} - - -static void -finalize_modules_delete_special(PyThreadState *tstate, int verbose) -{ - // List of names to clear in sys - static const char * const sys_deletes[] = { - "path", "argv", "ps1", "ps2", - "last_type", "last_value", "last_traceback", - "path_hooks", "path_importer_cache", "meta_path", - "__interactivehook__", - NULL - }; - - static const char * const sys_files[] = { - "stdin", "__stdin__", - "stdout", "__stdout__", - "stderr", "__stderr__", - NULL - }; - - PyInterpreterState *interp = tstate->interp; - if (verbose) { - PySys_WriteStderr("# clear builtins._\n"); - } - if (PyDict_SetItemString(interp->builtins, "_", Py_None) < 0) { - PyErr_WriteUnraisable(NULL); - } - - const char * const *p; - for (p = sys_deletes; *p != NULL; p++) { - if (verbose) { - PySys_WriteStderr("# clear sys.%s\n", *p); - } - if (PyDict_SetItemString(interp->sysdict, *p, Py_None) < 0) { - PyErr_WriteUnraisable(NULL); - } - } - for (p = sys_files; *p != NULL; p+=2) { - const char *name = p[0]; - const char *orig_name = p[1]; - if (verbose) { - PySys_WriteStderr("# restore sys.%s\n", name); - } - PyObject *value = _PyDict_GetItemStringWithError(interp->sysdict, - orig_name); - if (value == NULL) { - if (_PyErr_Occurred(tstate)) { - PyErr_WriteUnraisable(NULL); - } - value = Py_None; - } - if (PyDict_SetItemString(interp->sysdict, name, value) < 0) { - PyErr_WriteUnraisable(NULL); - } - } -} - - -static PyObject* -finalize_remove_modules(PyObject *modules, int verbose) -{ - PyObject *weaklist = PyList_New(0); - if (weaklist == NULL) { - PyErr_WriteUnraisable(NULL); - } - -#define STORE_MODULE_WEAKREF(name, mod) \ - if (weaklist != NULL) { \ - PyObject *wr = PyWeakref_NewRef(mod, NULL); \ - if (wr) { \ - PyObject *tup = PyTuple_Pack(2, name, wr); \ - if (!tup || PyList_Append(weaklist, tup) < 0) { \ - PyErr_WriteUnraisable(NULL); \ - } \ - Py_XDECREF(tup); \ - Py_DECREF(wr); \ - } \ - else { \ - PyErr_WriteUnraisable(NULL); \ - } \ - } - -#define CLEAR_MODULE(name, mod) \ - if (PyModule_Check(mod)) { \ - if (verbose && PyUnicode_Check(name)) { \ - PySys_FormatStderr("# cleanup[2] removing %U\n", name); \ - } \ - STORE_MODULE_WEAKREF(name, mod); \ - if (PyObject_SetItem(modules, name, Py_None) < 0) { \ - PyErr_WriteUnraisable(NULL); \ - } \ - } - - if (PyDict_CheckExact(modules)) { - Py_ssize_t pos = 0; - PyObject *key, *value; - while (PyDict_Next(modules, &pos, &key, &value)) { - CLEAR_MODULE(key, value); - } - } - else { - PyObject *iterator = PyObject_GetIter(modules); - if (iterator == NULL) { - PyErr_WriteUnraisable(NULL); - } - else { - PyObject *key; - while ((key = PyIter_Next(iterator))) { - PyObject *value = PyObject_GetItem(modules, key); - if (value == NULL) { - PyErr_WriteUnraisable(NULL); - continue; - } - CLEAR_MODULE(key, value); - Py_DECREF(value); - Py_DECREF(key); - } - if (PyErr_Occurred()) { - PyErr_WriteUnraisable(NULL); - } - Py_DECREF(iterator); - } - } -#undef CLEAR_MODULE -#undef STORE_MODULE_WEAKREF - - return weaklist; -} - - -static void -finalize_clear_modules_dict(PyObject *modules) -{ - if (PyDict_CheckExact(modules)) { - PyDict_Clear(modules); - } - else { - _Py_IDENTIFIER(clear); - if (_PyObject_CallMethodIdNoArgs(modules, &PyId_clear) == NULL) { - PyErr_WriteUnraisable(NULL); - } - } -} - - -static void -finalize_restore_builtins(PyThreadState *tstate) -{ - PyInterpreterState *interp = tstate->interp; - PyObject *dict = PyDict_Copy(interp->builtins); - if (dict == NULL) { - PyErr_WriteUnraisable(NULL); - } - PyDict_Clear(interp->builtins); - if (PyDict_Update(interp->builtins, interp->builtins_copy)) { - _PyErr_Clear(tstate); - } - Py_XDECREF(dict); -} - - -static void -finalize_modules_clear_weaklist(PyInterpreterState *interp, - PyObject *weaklist, int verbose) -{ - // First clear modules imported later - for (Py_ssize_t i = PyList_GET_SIZE(weaklist) - 1; i >= 0; i--) { - PyObject *tup = PyList_GET_ITEM(weaklist, i); - PyObject *name = PyTuple_GET_ITEM(tup, 0); - PyObject *mod = PyWeakref_GET_OBJECT(PyTuple_GET_ITEM(tup, 1)); - if (mod == Py_None) { - continue; - } - assert(PyModule_Check(mod)); - PyObject *dict = PyModule_GetDict(mod); - if (dict == interp->builtins || dict == interp->sysdict) { - continue; - } - Py_INCREF(mod); - if (verbose && PyUnicode_Check(name)) { - PySys_FormatStderr("# cleanup[3] wiping %U\n", name); - } - _PyModule_Clear(mod); - Py_DECREF(mod); - } -} - - -static void -finalize_clear_sys_builtins_dict(PyInterpreterState *interp, int verbose) -{ - // Clear sys dict - if (verbose) { - PySys_FormatStderr("# cleanup[3] wiping sys\n"); - } - _PyModule_ClearDict(interp->sysdict); - - // Clear builtins dict - if (verbose) { - PySys_FormatStderr("# cleanup[3] wiping builtins\n"); - } - _PyModule_ClearDict(interp->builtins); -} - - -/* Clear modules, as good as we can */ -static void -finalize_modules(PyThreadState *tstate) -{ - PyInterpreterState *interp = tstate->interp; - PyObject *modules = interp->modules; - if (modules == NULL) { - // Already done - return; - } - int verbose = _PyInterpreterState_GetConfig(interp)->verbose; - - // Delete some special builtins._ and sys attributes first. These are - // common places where user values hide and people complain when their - // destructors fail. Since the modules containing them are - // deleted *last* of all, they would come too late in the normal - // destruction order. Sigh. - // - // XXX Perhaps these precautions are obsolete. Who knows? - finalize_modules_delete_special(tstate, verbose); - - // Remove all modules from sys.modules, hoping that garbage collection - // can reclaim most of them: set all sys.modules values to None. - // - // We prepare a list which will receive (name, weakref) tuples of - // modules when they are removed from sys.modules. The name is used - // for diagnosis messages (in verbose mode), while the weakref helps - // detect those modules which have been held alive. - PyObject *weaklist = finalize_remove_modules(modules, verbose); - - // Clear the modules dict - finalize_clear_modules_dict(modules); - - // Restore the original builtins dict, to ensure that any - // user data gets cleared. - finalize_restore_builtins(tstate); - - // Collect garbage - _PyGC_CollectNoFail(tstate); - - // Dump GC stats before it's too late, since it uses the warnings - // machinery. - _PyGC_DumpShutdownStats(interp); - - if (weaklist != NULL) { - // Now, if there are any modules left alive, clear their globals to - // minimize potential leaks. All C extension modules actually end - // up here, since they are kept alive in the interpreter state. - // - // The special treatment of "builtins" here is because even - // when it's not referenced as a module, its dictionary is - // referenced by almost every module's __builtins__. Since - // deleting a module clears its dictionary (even if there are - // references left to it), we need to delete the "builtins" - // module last. Likewise, we don't delete sys until the very - // end because it is implicitly referenced (e.g. by print). - // - // Since dict is ordered in CPython 3.6+, modules are saved in - // importing order. First clear modules imported later. - finalize_modules_clear_weaklist(interp, weaklist, verbose); - Py_DECREF(weaklist); - } - - // Clear sys and builtins modules dict - finalize_clear_sys_builtins_dict(interp, verbose); - - // Clear module dict copies stored in the interpreter state: - // clear PyInterpreterState.modules_by_index and - // clear PyModuleDef.m_base.m_copy (of extensions not using the multi-phase - // initialization API) - _PyInterpreterState_ClearModules(interp); - - // Clear and delete the modules directory. Actual modules will - // still be there only if imported during the execution of some - // destructor. - Py_SETREF(interp->modules, NULL); - - // Collect garbage once more - _PyGC_CollectNoFail(tstate); -} - - -/* Flush stdout and stderr */ - -static int -file_is_closed(PyObject *fobj) -{ - int r; - PyObject *tmp = PyObject_GetAttrString(fobj, "closed"); - if (tmp == NULL) { - PyErr_Clear(); - return 0; - } - r = PyObject_IsTrue(tmp); - Py_DECREF(tmp); - if (r < 0) - PyErr_Clear(); - return r > 0; -} - - -static int -flush_std_files(void) -{ - PyObject *fout = _PySys_GetObjectId(&PyId_stdout); - PyObject *ferr = _PySys_GetObjectId(&PyId_stderr); - PyObject *tmp; - int status = 0; - - if (fout != NULL && fout != Py_None && !file_is_closed(fout)) { - tmp = _PyObject_CallMethodIdNoArgs(fout, &PyId_flush); - if (tmp == NULL) { - PyErr_WriteUnraisable(fout); - status = -1; - } - else - Py_DECREF(tmp); - } - - if (ferr != NULL && ferr != Py_None && !file_is_closed(ferr)) { - tmp = _PyObject_CallMethodIdNoArgs(ferr, &PyId_flush); - if (tmp == NULL) { - PyErr_Clear(); - status = -1; - } - else - Py_DECREF(tmp); - } - - return status; -} - -/* Undo the effect of Py_Initialize(). - - Beware: if multiple interpreter and/or thread states exist, these - are not wiped out; only the current thread and interpreter state - are deleted. But since everything else is deleted, those other - interpreter and thread states should no longer be used. - - (XXX We should do better, e.g. wipe out all interpreters and - threads.) - - Locking: as above. - -*/ - - -static void -finalize_interp_types(PyInterpreterState *interp) -{ - _PyExc_Fini(interp); - _PyFrame_Fini(interp); - _PyAsyncGen_Fini(interp); - _PyContext_Fini(interp); - _PyType_Fini(interp); - // Call _PyUnicode_ClearInterned() before _PyDict_Fini() since it uses - // a dict internally. - _PyUnicode_ClearInterned(interp); - - _PyDict_Fini(interp); - _PyList_Fini(interp); - _PyTuple_Fini(interp); - - _PySlice_Fini(interp); - - _PyBytes_Fini(interp); - _PyUnicode_Fini(interp); - _PyFloat_Fini(interp); - _PyLong_Fini(interp); -} - - -static void -finalize_interp_clear(PyThreadState *tstate) -{ - int is_main_interp = _Py_IsMainInterpreter(tstate->interp); - - /* Clear interpreter state and all thread states */ - _PyInterpreterState_Clear(tstate); - - /* Clear all loghooks */ - /* Both _PySys_Audit function and users still need PyObject, such as tuple. - Call _PySys_ClearAuditHooks when PyObject available. */ - if (is_main_interp) { - _PySys_ClearAuditHooks(tstate); - } - - if (is_main_interp) { - _Py_HashRandomization_Fini(); - _PyArg_Fini(); - _Py_ClearFileSystemEncoding(); - } - - finalize_interp_types(tstate->interp); -} - - -static void -finalize_interp_delete(PyInterpreterState *interp) -{ - if (_Py_IsMainInterpreter(interp)) { - /* Cleanup auto-thread-state */ - _PyGILState_Fini(interp); - } - - /* We can't call _PyEval_FiniGIL() here because destroying the GIL lock can - fail when it is being awaited by another running daemon thread (see - bpo-9901). Instead pycore_create_interpreter() destroys the previously - created GIL, which ensures that Py_Initialize / Py_FinalizeEx can be - called multiple times. */ - - PyInterpreterState_Delete(interp); -} - - -int -Py_FinalizeEx(void) -{ - int status = 0; - - _PyRuntimeState *runtime = &_PyRuntime; - if (!runtime->initialized) { - return status; - } - - /* Get current thread state and interpreter pointer */ - PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); - - // Wrap up existing "threading"-module-created, non-daemon threads. - wait_for_thread_shutdown(tstate); - - // Make any remaining pending calls. - _Py_FinishPendingCalls(tstate); - - /* The interpreter is still entirely intact at this point, and the - * exit funcs may be relying on that. In particular, if some thread - * or exit func is still waiting to do an import, the import machinery - * expects Py_IsInitialized() to return true. So don't say the - * runtime is uninitialized until after the exit funcs have run. - * Note that Threading.py uses an exit func to do a join on all the - * threads created thru it, so this also protects pending imports in - * the threads created via Threading. - */ - - _PyAtExit_Call(tstate->interp); - - /* Copy the core config, PyInterpreterState_Delete() free - the core config memory */ -#ifdef Py_REF_DEBUG - int show_ref_count = tstate->interp->config.show_ref_count; -#endif -#ifdef Py_TRACE_REFS - int dump_refs = tstate->interp->config.dump_refs; -#endif -#ifdef WITH_PYMALLOC - int malloc_stats = tstate->interp->config.malloc_stats; -#endif - - /* Remaining daemon threads will automatically exit - when they attempt to take the GIL (ex: PyEval_RestoreThread()). */ - _PyRuntimeState_SetFinalizing(runtime, tstate); - runtime->initialized = 0; - runtime->core_initialized = 0; - - /* Destroy the state of all threads of the interpreter, except of the - current thread. In practice, only daemon threads should still be alive, - except if wait_for_thread_shutdown() has been cancelled by CTRL+C. - Clear frames of other threads to call objects destructors. Destructors - will be called in the current Python thread. Since - _PyRuntimeState_SetFinalizing() has been called, no other Python thread - can take the GIL at this point: if they try, they will exit - immediately. */ - _PyThreadState_DeleteExcept(runtime, tstate); - - /* Flush sys.stdout and sys.stderr */ - if (flush_std_files() < 0) { - status = -1; - } - - /* Disable signal handling */ - _PySignal_Fini(); - - /* Collect garbage. This may call finalizers; it's nice to call these - * before all modules are destroyed. - * XXX If a __del__ or weakref callback is triggered here, and tries to - * XXX import a module, bad things can happen, because Python no - * XXX longer believes it's initialized. - * XXX Fatal Python error: Interpreter not initialized (version mismatch?) - * XXX is easy to provoke that way. I've also seen, e.g., - * XXX Exception exceptions.ImportError: 'No module named sha' - * XXX in <function callback at 0x008F5718> ignored - * XXX but I'm unclear on exactly how that one happens. In any case, - * XXX I haven't seen a real-life report of either of these. - */ - PyGC_Collect(); - - /* Destroy all modules */ - finalize_modules(tstate); - - /* Print debug stats if any */ - _PyEval_Fini(); - - /* Flush sys.stdout and sys.stderr (again, in case more was printed) */ - if (flush_std_files() < 0) { - status = -1; - } - - /* Collect final garbage. This disposes of cycles created by - * class definitions, for example. - * XXX This is disabled because it caused too many problems. If - * XXX a __del__ or weakref callback triggers here, Python code has - * XXX a hard time running, because even the sys module has been - * XXX cleared out (sys.stdout is gone, sys.excepthook is gone, etc). - * XXX One symptom is a sequence of information-free messages - * XXX coming from threads (if a __del__ or callback is invoked, - * XXX other threads can execute too, and any exception they encounter - * XXX triggers a comedy of errors as subsystem after subsystem - * XXX fails to find what it *expects* to find in sys to help report - * XXX the exception and consequent unexpected failures). I've also - * XXX seen segfaults then, after adding print statements to the - * XXX Python code getting called. - */ -#if 0 - _PyGC_CollectIfEnabled(); -#endif - - /* Disable tracemalloc after all Python objects have been destroyed, - so it is possible to use tracemalloc in objects destructor. */ - _PyTraceMalloc_Fini(); - - /* Destroy the database used by _PyImport_{Fixup,Find}Extension */ - _PyImport_Fini(); - - /* unload faulthandler module */ - _PyFaulthandler_Fini(); - - /* dump hash stats */ - _PyHash_Fini(); - -#ifdef Py_REF_DEBUG - if (show_ref_count) { - _PyDebug_PrintTotalRefs(); - } -#endif - -#ifdef Py_TRACE_REFS - /* Display all objects still alive -- this can invoke arbitrary - * __repr__ overrides, so requires a mostly-intact interpreter. - * Alas, a lot of stuff may still be alive now that will be cleaned - * up later. - */ - if (dump_refs) { - _Py_PrintReferences(stderr); - } -#endif /* Py_TRACE_REFS */ - - finalize_interp_clear(tstate); - finalize_interp_delete(tstate->interp); - -#ifdef Py_TRACE_REFS - /* Display addresses (& refcnts) of all objects still alive. - * An address can be used to find the repr of the object, printed - * above by _Py_PrintReferences. - */ - if (dump_refs) { - _Py_PrintReferenceAddresses(stderr); - } -#endif /* Py_TRACE_REFS */ -#ifdef WITH_PYMALLOC - if (malloc_stats) { - _PyObject_DebugMallocStats(stderr); - } -#endif - - call_ll_exitfuncs(runtime); - - _PyRuntime_Finalize(); - return status; -} - -void -Py_Finalize(void) -{ - Py_FinalizeEx(); -} - - -/* Create and initialize a new interpreter and thread, and return the - new thread. This requires that Py_Initialize() has been called - first. - - Unsuccessful initialization yields a NULL pointer. Note that *no* - exception information is available even in this case -- the - exception information is held in the thread, and there is no - thread. - - Locking: as above. - -*/ - -static PyStatus -new_interpreter(PyThreadState **tstate_p, int isolated_subinterpreter) -{ - PyStatus status; - - status = _PyRuntime_Initialize(); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - _PyRuntimeState *runtime = &_PyRuntime; - - if (!runtime->initialized) { - return _PyStatus_ERR("Py_Initialize must be called first"); - } - - /* Issue #10915, #15751: The GIL API doesn't work with multiple - interpreters: disable PyGILState_Check(). */ - runtime->gilstate.check_enabled = 0; - - PyInterpreterState *interp = PyInterpreterState_New(); - if (interp == NULL) { - *tstate_p = NULL; - return _PyStatus_OK(); - } - - PyThreadState *tstate = PyThreadState_New(interp); - if (tstate == NULL) { - PyInterpreterState_Delete(interp); - *tstate_p = NULL; - return _PyStatus_OK(); - } - - PyThreadState *save_tstate = PyThreadState_Swap(tstate); - - /* Copy the current interpreter config into the new interpreter */ - const PyConfig *config; -#ifndef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS - if (save_tstate != NULL) { - config = _PyInterpreterState_GetConfig(save_tstate->interp); - } - else -#endif - { - /* No current thread state, copy from the main interpreter */ - PyInterpreterState *main_interp = PyInterpreterState_Main(); - config = _PyInterpreterState_GetConfig(main_interp); - } - - - status = _PyConfig_Copy(&interp->config, config); - if (_PyStatus_EXCEPTION(status)) { - goto error; - } - interp->config._isolated_interpreter = isolated_subinterpreter; - - status = init_interp_create_gil(tstate); - if (_PyStatus_EXCEPTION(status)) { - goto error; - } - - status = pycore_interp_init(tstate); - if (_PyStatus_EXCEPTION(status)) { - goto error; - } - - status = init_interp_main(tstate); - if (_PyStatus_EXCEPTION(status)) { - goto error; - } - - *tstate_p = tstate; - return _PyStatus_OK(); - -error: - *tstate_p = NULL; - - /* Oops, it didn't work. Undo it all. */ - PyErr_PrintEx(0); - PyThreadState_Clear(tstate); - PyThreadState_Delete(tstate); - PyInterpreterState_Delete(interp); - PyThreadState_Swap(save_tstate); - - return status; -} - -PyThreadState * -_Py_NewInterpreter(int isolated_subinterpreter) -{ - PyThreadState *tstate = NULL; - PyStatus status = new_interpreter(&tstate, isolated_subinterpreter); - if (_PyStatus_EXCEPTION(status)) { - Py_ExitStatusException(status); - } - return tstate; - -} - -PyThreadState * -Py_NewInterpreter(void) -{ - return _Py_NewInterpreter(0); -} - -/* Delete an interpreter and its last thread. This requires that the - given thread state is current, that the thread has no remaining - frames, and that it is its interpreter's only remaining thread. - It is a fatal error to violate these constraints. - - (Py_FinalizeEx() doesn't have these constraints -- it zaps - everything, regardless.) - - Locking: as above. - -*/ - -void -Py_EndInterpreter(PyThreadState *tstate) -{ - PyInterpreterState *interp = tstate->interp; - - if (tstate != _PyThreadState_GET()) { - Py_FatalError("thread is not current"); - } - if (tstate->frame != NULL) { - Py_FatalError("thread still has a frame"); - } - interp->finalizing = 1; - - // Wrap up existing "threading"-module-created, non-daemon threads. - wait_for_thread_shutdown(tstate); - - _PyAtExit_Call(tstate->interp); - - if (tstate != interp->tstate_head || tstate->next != NULL) { - Py_FatalError("not the last thread"); - } - - finalize_modules(tstate); - - finalize_interp_clear(tstate); - finalize_interp_delete(tstate->interp); -} - -/* Add the __main__ module */ - -static PyStatus -add_main_module(PyInterpreterState *interp) -{ - PyObject *m, *d, *loader, *ann_dict; - m = PyImport_AddModule("__main__"); - if (m == NULL) - return _PyStatus_ERR("can't create __main__ module"); - - d = PyModule_GetDict(m); - ann_dict = PyDict_New(); - if ((ann_dict == NULL) || - (PyDict_SetItemString(d, "__annotations__", ann_dict) < 0)) { - return _PyStatus_ERR("Failed to initialize __main__.__annotations__"); - } - Py_DECREF(ann_dict); - - if (_PyDict_GetItemStringWithError(d, "__builtins__") == NULL) { - if (PyErr_Occurred()) { - return _PyStatus_ERR("Failed to test __main__.__builtins__"); - } - PyObject *bimod = PyImport_ImportModule("builtins"); - if (bimod == NULL) { - return _PyStatus_ERR("Failed to retrieve builtins module"); - } - if (PyDict_SetItemString(d, "__builtins__", bimod) < 0) { - return _PyStatus_ERR("Failed to initialize __main__.__builtins__"); - } - Py_DECREF(bimod); - } - - /* Main is a little special - imp.is_builtin("__main__") will return - * False, but BuiltinImporter is still the most appropriate initial - * setting for its __loader__ attribute. A more suitable value will - * be set if __main__ gets further initialized later in the startup - * process. - */ - loader = _PyDict_GetItemStringWithError(d, "__loader__"); - if (loader == NULL || loader == Py_None) { - if (PyErr_Occurred()) { - return _PyStatus_ERR("Failed to test __main__.__loader__"); - } - PyObject *loader = PyObject_GetAttrString(interp->importlib, - "BuiltinImporter"); - if (loader == NULL) { - return _PyStatus_ERR("Failed to retrieve BuiltinImporter"); - } - if (PyDict_SetItemString(d, "__loader__", loader) < 0) { - return _PyStatus_ERR("Failed to initialize __main__.__loader__"); - } - Py_DECREF(loader); - } - return _PyStatus_OK(); -} - -/* Import the site module (not into __main__ though) */ - -static PyStatus -init_import_site(void) -{ - PyObject *m; - m = PyImport_ImportModule("site"); - if (m == NULL) { - return _PyStatus_ERR("Failed to import the site module"); - } - Py_DECREF(m); - return _PyStatus_OK(); -} - -/* Check if a file descriptor is valid or not. - Return 0 if the file descriptor is invalid, return non-zero otherwise. */ -static int -is_valid_fd(int fd) -{ -/* dup() is faster than fstat(): fstat() can require input/output operations, - whereas dup() doesn't. There is a low risk of EMFILE/ENFILE at Python - startup. Problem: dup() doesn't check if the file descriptor is valid on - some platforms. - - bpo-30225: On macOS Tiger, when stdout is redirected to a pipe and the other - side of the pipe is closed, dup(1) succeed, whereas fstat(1, &st) fails with - EBADF. FreeBSD has similar issue (bpo-32849). - - Only use dup() on platforms where dup() is enough to detect invalid FD in - corner cases: on Linux and Windows (bpo-32849). */ -#if defined(__linux__) || defined(MS_WINDOWS) - if (fd < 0) { - return 0; - } - int fd2; - - _Py_BEGIN_SUPPRESS_IPH - fd2 = dup(fd); - if (fd2 >= 0) { - close(fd2); - } - _Py_END_SUPPRESS_IPH - - return (fd2 >= 0); -#else - struct stat st; - return (fstat(fd, &st) == 0); -#endif -} - -/* returns Py_None if the fd is not valid */ -static PyObject* -create_stdio(const PyConfig *config, PyObject* io, - int fd, int write_mode, const char* name, - const wchar_t* encoding, const wchar_t* errors) -{ - PyObject *buf = NULL, *stream = NULL, *text = NULL, *raw = NULL, *res; - const char* mode; - const char* newline; - PyObject *line_buffering, *write_through; - int buffering, isatty; - _Py_IDENTIFIER(open); - _Py_IDENTIFIER(isatty); - _Py_IDENTIFIER(TextIOWrapper); - _Py_IDENTIFIER(mode); - const int buffered_stdio = config->buffered_stdio; - - if (!is_valid_fd(fd)) - Py_RETURN_NONE; - - /* stdin is always opened in buffered mode, first because it shouldn't - make a difference in common use cases, second because TextIOWrapper - depends on the presence of a read1() method which only exists on - buffered streams. - */ - if (!buffered_stdio && write_mode) - buffering = 0; - else - buffering = -1; - if (write_mode) - mode = "wb"; - else - mode = "rb"; - buf = _PyObject_CallMethodId(io, &PyId_open, "isiOOOO", - fd, mode, buffering, - Py_None, Py_None, /* encoding, errors */ - Py_None, Py_False); /* newline, closefd */ - if (buf == NULL) - goto error; - - if (buffering) { - _Py_IDENTIFIER(raw); - raw = _PyObject_GetAttrId(buf, &PyId_raw); - if (raw == NULL) - goto error; - } - else { - raw = buf; - Py_INCREF(raw); - } - -#ifdef MS_WINDOWS - /* Windows console IO is always UTF-8 encoded */ - if (PyWindowsConsoleIO_Check(raw)) - encoding = L"utf-8"; -#endif - - text = PyUnicode_FromString(name); - if (text == NULL || _PyObject_SetAttrId(raw, &PyId_name, text) < 0) - goto error; - res = _PyObject_CallMethodIdNoArgs(raw, &PyId_isatty); - if (res == NULL) - goto error; - isatty = PyObject_IsTrue(res); - Py_DECREF(res); - if (isatty == -1) - goto error; - if (!buffered_stdio) - write_through = Py_True; - else - write_through = Py_False; - if (buffered_stdio && (isatty || fd == fileno(stderr))) - line_buffering = Py_True; - else - line_buffering = Py_False; - - Py_CLEAR(raw); - Py_CLEAR(text); - -#ifdef MS_WINDOWS - /* sys.stdin: enable universal newline mode, translate "\r\n" and "\r" - newlines to "\n". - sys.stdout and sys.stderr: translate "\n" to "\r\n". */ - newline = NULL; -#else - /* sys.stdin: split lines at "\n". - sys.stdout and sys.stderr: don't translate newlines (use "\n"). */ - newline = "\n"; -#endif - - PyObject *encoding_str = PyUnicode_FromWideChar(encoding, -1); - if (encoding_str == NULL) { - Py_CLEAR(buf); - goto error; - } - - PyObject *errors_str = PyUnicode_FromWideChar(errors, -1); - if (errors_str == NULL) { - Py_CLEAR(buf); - Py_CLEAR(encoding_str); - goto error; - } - - stream = _PyObject_CallMethodId(io, &PyId_TextIOWrapper, "OOOsOO", - buf, encoding_str, errors_str, - newline, line_buffering, write_through); - Py_CLEAR(buf); - Py_CLEAR(encoding_str); - Py_CLEAR(errors_str); - if (stream == NULL) - goto error; - - if (write_mode) - mode = "w"; - else - mode = "r"; - text = PyUnicode_FromString(mode); - if (!text || _PyObject_SetAttrId(stream, &PyId_mode, text) < 0) - goto error; - Py_CLEAR(text); - return stream; - -error: - Py_XDECREF(buf); - Py_XDECREF(stream); - Py_XDECREF(text); - Py_XDECREF(raw); - - if (PyErr_ExceptionMatches(PyExc_OSError) && !is_valid_fd(fd)) { - /* Issue #24891: the file descriptor was closed after the first - is_valid_fd() check was called. Ignore the OSError and set the - stream to None. */ - PyErr_Clear(); - Py_RETURN_NONE; - } - return NULL; -} - -/* Set builtins.open to io.open */ -static PyStatus -init_set_builtins_open(void) -{ - PyObject *iomod = NULL, *wrapper; - PyObject *bimod = NULL; - PyStatus res = _PyStatus_OK(); - - if (!(iomod = PyImport_ImportModule("io"))) { - goto error; - } - - if (!(bimod = PyImport_ImportModule("builtins"))) { - goto error; - } - - if (!(wrapper = PyObject_GetAttrString(iomod, "open"))) { - goto error; - } - - /* Set builtins.open */ - if (PyObject_SetAttrString(bimod, "open", wrapper) == -1) { - Py_DECREF(wrapper); - goto error; - } - Py_DECREF(wrapper); - goto done; - -error: - res = _PyStatus_ERR("can't initialize io.open"); - -done: - Py_XDECREF(bimod); - Py_XDECREF(iomod); - return res; -} - - -/* Create sys.stdin, sys.stdout and sys.stderr */ -static PyStatus -init_sys_streams(PyThreadState *tstate) -{ - PyObject *iomod = NULL; - PyObject *std = NULL; - int fd; - PyObject * encoding_attr; - PyStatus res = _PyStatus_OK(); - const PyConfig *config = _PyInterpreterState_GetConfig(tstate->interp); - - /* Check that stdin is not a directory - Using shell redirection, you can redirect stdin to a directory, - crashing the Python interpreter. Catch this common mistake here - and output a useful error message. Note that under MS Windows, - the shell already prevents that. */ -#ifndef MS_WINDOWS - struct _Py_stat_struct sb; - if (_Py_fstat_noraise(fileno(stdin), &sb) == 0 && - S_ISDIR(sb.st_mode)) { - return _PyStatus_ERR("<stdin> is a directory, cannot continue"); - } -#endif - - if (!(iomod = PyImport_ImportModule("io"))) { - goto error; - } - - /* Set sys.stdin */ - fd = fileno(stdin); - /* Under some conditions stdin, stdout and stderr may not be connected - * and fileno() may point to an invalid file descriptor. For example - * GUI apps don't have valid standard streams by default. - */ - std = create_stdio(config, iomod, fd, 0, "<stdin>", - config->stdio_encoding, - config->stdio_errors); - if (std == NULL) - goto error; - PySys_SetObject("__stdin__", std); - _PySys_SetObjectId(&PyId_stdin, std); - Py_DECREF(std); - - /* Set sys.stdout */ - fd = fileno(stdout); - std = create_stdio(config, iomod, fd, 1, "<stdout>", - config->stdio_encoding, - config->stdio_errors); - if (std == NULL) - goto error; - PySys_SetObject("__stdout__", std); - _PySys_SetObjectId(&PyId_stdout, std); - Py_DECREF(std); - -#if 1 /* Disable this if you have trouble debugging bootstrap stuff */ - /* Set sys.stderr, replaces the preliminary stderr */ - fd = fileno(stderr); - std = create_stdio(config, iomod, fd, 1, "<stderr>", - config->stdio_encoding, - L"backslashreplace"); - if (std == NULL) - goto error; - - /* Same as hack above, pre-import stderr's codec to avoid recursion - when import.c tries to write to stderr in verbose mode. */ - encoding_attr = PyObject_GetAttrString(std, "encoding"); - if (encoding_attr != NULL) { - const char *std_encoding = PyUnicode_AsUTF8(encoding_attr); - if (std_encoding != NULL) { - PyObject *codec_info = _PyCodec_Lookup(std_encoding); - Py_XDECREF(codec_info); - } - Py_DECREF(encoding_attr); - } - _PyErr_Clear(tstate); /* Not a fatal error if codec isn't available */ - - if (PySys_SetObject("__stderr__", std) < 0) { - Py_DECREF(std); - goto error; - } - if (_PySys_SetObjectId(&PyId_stderr, std) < 0) { - Py_DECREF(std); - goto error; - } - Py_DECREF(std); -#endif - - goto done; - -error: - res = _PyStatus_ERR("can't initialize sys standard streams"); - -done: - _Py_ClearStandardStreamEncoding(); - Py_XDECREF(iomod); - return res; -} - - -static void -_Py_FatalError_DumpTracebacks(int fd, PyInterpreterState *interp, - PyThreadState *tstate) -{ - PUTS(fd, "\n"); - - /* display the current Python stack */ - _Py_DumpTracebackThreads(fd, interp, tstate); -} - -/* Print the current exception (if an exception is set) with its traceback, - or display the current Python stack. - - Don't call PyErr_PrintEx() and the except hook, because Py_FatalError() is - called on catastrophic cases. - - Return 1 if the traceback was displayed, 0 otherwise. */ - -static int -_Py_FatalError_PrintExc(PyThreadState *tstate) -{ - PyObject *ferr, *res; - PyObject *exception, *v, *tb; - int has_tb; - - _PyErr_Fetch(tstate, &exception, &v, &tb); - if (exception == NULL) { - /* No current exception */ - return 0; - } - - ferr = _PySys_GetObjectId(&PyId_stderr); - if (ferr == NULL || ferr == Py_None) { - /* sys.stderr is not set yet or set to None, - no need to try to display the exception */ - return 0; - } - - _PyErr_NormalizeException(tstate, &exception, &v, &tb); - if (tb == NULL) { - tb = Py_None; - Py_INCREF(tb); - } - PyException_SetTraceback(v, tb); - if (exception == NULL) { - /* PyErr_NormalizeException() failed */ - return 0; - } - - has_tb = (tb != Py_None); - PyErr_Display(exception, v, tb); - Py_XDECREF(exception); - Py_XDECREF(v); - Py_XDECREF(tb); - - /* sys.stderr may be buffered: call sys.stderr.flush() */ - res = _PyObject_CallMethodIdNoArgs(ferr, &PyId_flush); - if (res == NULL) { - _PyErr_Clear(tstate); - } - else { - Py_DECREF(res); - } - - return has_tb; -} - -/* Print fatal error message and abort */ - -#ifdef MS_WINDOWS -static void -fatal_output_debug(const char *msg) -{ - /* buffer of 256 bytes allocated on the stack */ - WCHAR buffer[256 / sizeof(WCHAR)]; - size_t buflen = Py_ARRAY_LENGTH(buffer) - 1; - size_t msglen; - - OutputDebugStringW(L"Fatal Python error: "); - - msglen = strlen(msg); - while (msglen) { - size_t i; - - if (buflen > msglen) { - buflen = msglen; - } - - /* Convert the message to wchar_t. This uses a simple one-to-one - conversion, assuming that the this error message actually uses - ASCII only. If this ceases to be true, we will have to convert. */ - for (i=0; i < buflen; ++i) { - buffer[i] = msg[i]; - } - buffer[i] = L'\0'; - OutputDebugStringW(buffer); - - msg += buflen; - msglen -= buflen; - } - OutputDebugStringW(L"\n"); -} -#endif - - -static void -fatal_error_dump_runtime(int fd, _PyRuntimeState *runtime) -{ - PUTS(fd, "Python runtime state: "); - PyThreadState *finalizing = _PyRuntimeState_GetFinalizing(runtime); - if (finalizing) { - PUTS(fd, "finalizing (tstate=0x"); - _Py_DumpHexadecimal(fd, (uintptr_t)finalizing, sizeof(finalizing) * 2); - PUTS(fd, ")"); - } - else if (runtime->initialized) { - PUTS(fd, "initialized"); - } - else if (runtime->core_initialized) { - PUTS(fd, "core initialized"); - } - else if (runtime->preinitialized) { - PUTS(fd, "preinitialized"); - } - else if (runtime->preinitializing) { - PUTS(fd, "preinitializing"); - } - else { - PUTS(fd, "unknown"); - } - PUTS(fd, "\n"); -} - - -static inline void _Py_NO_RETURN -fatal_error_exit(int status) -{ - if (status < 0) { -#if defined(MS_WINDOWS) && defined(_DEBUG) - DebugBreak(); -#endif - abort(); - } - else { - exit(status); - } -} - - -// Dump the list of extension modules of sys.modules, excluding stdlib modules -// (sys.stdlib_module_names), into fd file descriptor. -// -// This function is called by a signal handler in faulthandler: avoid memory -// allocations and keep the implementation simple. For example, the list is not -// sorted on purpose. -void -_Py_DumpExtensionModules(int fd, PyInterpreterState *interp) -{ - if (interp == NULL) { - return; - } - PyObject *modules = interp->modules; - if (modules == NULL || !PyDict_Check(modules)) { - return; - } - - Py_ssize_t pos; - PyObject *key, *value; - - // Avoid PyDict_GetItemString() which calls PyUnicode_FromString(), - // memory cannot be allocated on the heap in a signal handler. - // Iterate on the dict instead. - PyObject *stdlib_module_names = NULL; - if (interp->sysdict != NULL) { - pos = 0; - while (PyDict_Next(interp->sysdict, &pos, &key, &value)) { - if (PyUnicode_Check(key) - && PyUnicode_CompareWithASCIIString(key, "stdlib_module_names") == 0) { - stdlib_module_names = value; - break; - } - } - } - // If we failed to get sys.stdlib_module_names or it's not a frozenset, - // don't exclude stdlib modules. - if (stdlib_module_names != NULL && !PyFrozenSet_Check(stdlib_module_names)) { - stdlib_module_names = NULL; - } - - // List extensions - int header = 1; - Py_ssize_t count = 0; - pos = 0; - while (PyDict_Next(modules, &pos, &key, &value)) { - if (!PyUnicode_Check(key)) { - continue; - } - if (!_PyModule_IsExtension(value)) { - continue; - } - // Use the module name from the sys.modules key, - // don't attempt to get the module object name. - if (stdlib_module_names != NULL) { - int is_stdlib_ext = 0; - - Py_ssize_t i = 0; - PyObject *item; - Py_hash_t hash; - while (_PySet_NextEntry(stdlib_module_names, &i, &item, &hash)) { - if (PyUnicode_Check(item) - && PyUnicode_Compare(key, item) == 0) - { - is_stdlib_ext = 1; - break; - } - } - if (is_stdlib_ext) { - // Ignore stdlib extension - continue; - } - } - - if (header) { - PUTS(fd, "\nExtension modules: "); - header = 0; - } - else { - PUTS(fd, ", "); - } - - _Py_DumpASCII(fd, key); - count++; - } - - if (count) { - PUTS(fd, " (total: "); - _Py_DumpDecimal(fd, count); - PUTS(fd, ")"); - PUTS(fd, "\n"); - } -} - - -static void _Py_NO_RETURN -fatal_error(int fd, int header, const char *prefix, const char *msg, - int status) -{ - static int reentrant = 0; - - if (reentrant) { - /* Py_FatalError() caused a second fatal error. - Example: flush_std_files() raises a recursion error. */ - fatal_error_exit(status); - } - reentrant = 1; - - if (header) { - PUTS(fd, "Fatal Python error: "); - if (prefix) { - PUTS(fd, prefix); - PUTS(fd, ": "); - } - if (msg) { - PUTS(fd, msg); - } - else { - PUTS(fd, "<message not set>"); - } - PUTS(fd, "\n"); - } - - _PyRuntimeState *runtime = &_PyRuntime; - fatal_error_dump_runtime(fd, runtime); - - /* Check if the current thread has a Python thread state - and holds the GIL. - - tss_tstate is NULL if Py_FatalError() is called from a C thread which - has no Python thread state. - - tss_tstate != tstate if the current Python thread does not hold the GIL. - */ - PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); - PyInterpreterState *interp = NULL; - PyThreadState *tss_tstate = PyGILState_GetThisThreadState(); - if (tstate != NULL) { - interp = tstate->interp; - } - else if (tss_tstate != NULL) { - interp = tss_tstate->interp; - } - int has_tstate_and_gil = (tss_tstate != NULL && tss_tstate == tstate); - - if (has_tstate_and_gil) { - /* If an exception is set, print the exception with its traceback */ - if (!_Py_FatalError_PrintExc(tss_tstate)) { - /* No exception is set, or an exception is set without traceback */ - _Py_FatalError_DumpTracebacks(fd, interp, tss_tstate); - } - } - else { - _Py_FatalError_DumpTracebacks(fd, interp, tss_tstate); - } - - _Py_DumpExtensionModules(fd, interp); - - /* The main purpose of faulthandler is to display the traceback. - This function already did its best to display a traceback. - Disable faulthandler to prevent writing a second traceback - on abort(). */ - _PyFaulthandler_Fini(); - - /* Check if the current Python thread hold the GIL */ - if (has_tstate_and_gil) { - /* Flush sys.stdout and sys.stderr */ - flush_std_files(); - } - -#ifdef MS_WINDOWS - fatal_output_debug(msg); -#endif /* MS_WINDOWS */ - - fatal_error_exit(status); -} - - -#undef Py_FatalError - -void _Py_NO_RETURN -Py_FatalError(const char *msg) -{ - fatal_error(fileno(stderr), 1, NULL, msg, -1); -} - - -void _Py_NO_RETURN -_Py_FatalErrorFunc(const char *func, const char *msg) -{ - fatal_error(fileno(stderr), 1, func, msg, -1); -} - - -void _Py_NO_RETURN -_Py_FatalErrorFormat(const char *func, const char *format, ...) -{ - static int reentrant = 0; - if (reentrant) { - /* _Py_FatalErrorFormat() caused a second fatal error */ - fatal_error_exit(-1); - } - reentrant = 1; - - FILE *stream = stderr; - const int fd = fileno(stream); - PUTS(fd, "Fatal Python error: "); - if (func) { - PUTS(fd, func); - PUTS(fd, ": "); - } - - va_list vargs; -#ifdef HAVE_STDARG_PROTOTYPES - va_start(vargs, format); -#else - va_start(vargs); -#endif - vfprintf(stream, format, vargs); - va_end(vargs); - - fputs("\n", stream); - fflush(stream); - - fatal_error(fd, 0, NULL, NULL, -1); -} - - -void _Py_NO_RETURN -Py_ExitStatusException(PyStatus status) -{ - if (_PyStatus_IS_EXIT(status)) { - exit(status.exitcode); - } - else if (_PyStatus_IS_ERROR(status)) { - fatal_error(fileno(stderr), 1, status.func, status.err_msg, 1); - } - else { - Py_FatalError("Py_ExitStatusException() must not be called on success"); - } -} - - -/* Wait until threading._shutdown completes, provided - the threading module was imported in the first place. - The shutdown routine will wait until all non-daemon - "threading" threads have completed. */ -static void -wait_for_thread_shutdown(PyThreadState *tstate) -{ - _Py_IDENTIFIER(_shutdown); - PyObject *result; - PyObject *threading = _PyImport_GetModuleId(&PyId_threading); - if (threading == NULL) { - if (_PyErr_Occurred(tstate)) { - PyErr_WriteUnraisable(NULL); - } - /* else: threading not imported */ - return; - } - result = _PyObject_CallMethodIdNoArgs(threading, &PyId__shutdown); - if (result == NULL) { - PyErr_WriteUnraisable(threading); - } - else { - Py_DECREF(result); - } - Py_DECREF(threading); -} - -#define NEXITFUNCS 32 -int Py_AtExit(void (*func)(void)) -{ - if (_PyRuntime.nexitfuncs >= NEXITFUNCS) - return -1; - _PyRuntime.exitfuncs[_PyRuntime.nexitfuncs++] = func; - return 0; -} - -static void -call_ll_exitfuncs(_PyRuntimeState *runtime) -{ - while (runtime->nexitfuncs > 0) { - /* pop last function from the list */ - runtime->nexitfuncs--; - void (*exitfunc)(void) = runtime->exitfuncs[runtime->nexitfuncs]; - runtime->exitfuncs[runtime->nexitfuncs] = NULL; - - exitfunc(); - } - - fflush(stdout); - fflush(stderr); -} - -void _Py_NO_RETURN -Py_Exit(int sts) -{ - if (Py_FinalizeEx() < 0) { - sts = 120; - } - - exit(sts); -} - - -/* - * The file descriptor fd is considered ``interactive'' if either - * a) isatty(fd) is TRUE, or - * b) the -i flag was given, and the filename associated with - * the descriptor is NULL or "<stdin>" or "???". - */ -int -Py_FdIsInteractive(FILE *fp, const char *filename) -{ - if (isatty((int)fileno(fp))) - return 1; - if (!Py_InteractiveFlag) - return 0; - return (filename == NULL) || - (strcmp(filename, "<stdin>") == 0) || - (strcmp(filename, "???") == 0); -} - - -int -_Py_FdIsInteractive(FILE *fp, PyObject *filename) -{ - if (isatty((int)fileno(fp))) { - return 1; - } - if (!Py_InteractiveFlag) { - return 0; - } - return (filename == NULL) || - (PyUnicode_CompareWithASCIIString(filename, "<stdin>") == 0) || - (PyUnicode_CompareWithASCIIString(filename, "???") == 0); -} - - -/* Wrappers around sigaction() or signal(). */ - -PyOS_sighandler_t -PyOS_getsig(int sig) -{ -#ifdef HAVE_SIGACTION - struct sigaction context; - if (sigaction(sig, NULL, &context) == -1) - return SIG_ERR; - return context.sa_handler; -#else - PyOS_sighandler_t handler; -/* Special signal handling for the secure CRT in Visual Studio 2005 */ -#if defined(_MSC_VER) && _MSC_VER >= 1400 - switch (sig) { - /* Only these signals are valid */ - case SIGINT: - case SIGILL: - case SIGFPE: - case SIGSEGV: - case SIGTERM: - case SIGBREAK: - case SIGABRT: - break; - /* Don't call signal() with other values or it will assert */ - default: - return SIG_ERR; - } -#endif /* _MSC_VER && _MSC_VER >= 1400 */ - handler = signal(sig, SIG_IGN); - if (handler != SIG_ERR) - signal(sig, handler); - return handler; -#endif -} - -/* - * All of the code in this function must only use async-signal-safe functions, - * listed at `man 7 signal` or - * http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html. - */ -PyOS_sighandler_t -PyOS_setsig(int sig, PyOS_sighandler_t handler) -{ -#ifdef HAVE_SIGACTION - /* Some code in Modules/signalmodule.c depends on sigaction() being - * used here if HAVE_SIGACTION is defined. Fix that if this code - * changes to invalidate that assumption. - */ - struct sigaction context, ocontext; - context.sa_handler = handler; - sigemptyset(&context.sa_mask); - /* Using SA_ONSTACK is friendlier to other C/C++/Golang-VM code that - * extension module or embedding code may use where tiny thread stacks - * are used. https://bugs.python.org/issue43390 */ - context.sa_flags = SA_ONSTACK; - if (sigaction(sig, &context, &ocontext) == -1) - return SIG_ERR; - return ocontext.sa_handler; -#else - PyOS_sighandler_t oldhandler; - oldhandler = signal(sig, handler); -#ifdef HAVE_SIGINTERRUPT - siginterrupt(sig, 1); -#endif - return oldhandler; -#endif -} - -#ifdef __cplusplus -} -#endif diff --git a/contrib/tools/python3/src/Python/pymath.c b/contrib/tools/python3/src/Python/pymath.c deleted file mode 100644 index 24b804223ee..00000000000 --- a/contrib/tools/python3/src/Python/pymath.c +++ /dev/null @@ -1,81 +0,0 @@ -#include "Python.h" - -#ifdef X87_DOUBLE_ROUNDING -/* On x86 platforms using an x87 FPU, this function is called from the - Py_FORCE_DOUBLE macro (defined in pymath.h) to force a floating-point - number out of an 80-bit x87 FPU register and into a 64-bit memory location, - thus rounding from extended precision to double precision. */ -double _Py_force_double(double x) -{ - volatile double y; - y = x; - return y; -} -#endif - -#ifdef HAVE_GCC_ASM_FOR_X87 - -/* inline assembly for getting and setting the 387 FPU control word on - gcc/x86 */ -#ifdef _Py_MEMORY_SANITIZER -__attribute__((no_sanitize_memory)) -#endif -unsigned short _Py_get_387controlword(void) { - unsigned short cw; - __asm__ __volatile__ ("fnstcw %0" : "=m" (cw)); - return cw; -} - -void _Py_set_387controlword(unsigned short cw) { - __asm__ __volatile__ ("fldcw %0" : : "m" (cw)); -} - -#endif - - -#ifndef HAVE_HYPOT -double hypot(double x, double y) -{ - double yx; - - x = fabs(x); - y = fabs(y); - if (x < y) { - double temp = x; - x = y; - y = temp; - } - if (x == 0.) - return 0.; - else { - yx = y/x; - return x*sqrt(1.+yx*yx); - } -} -#endif /* HAVE_HYPOT */ - -#ifndef HAVE_COPYSIGN -double -copysign(double x, double y) -{ - /* use atan2 to distinguish -0. from 0. */ - if (y > 0. || (y == 0. && atan2(y, -1.) > 0.)) { - return fabs(x); - } else { - return -fabs(x); - } -} -#endif /* HAVE_COPYSIGN */ - -#ifndef HAVE_ROUND -double -round(double x) -{ - double absx, y; - absx = fabs(x); - y = floor(absx); - if (absx - y >= 0.5) - y += 1.0; - return copysign(y, x); -} -#endif /* HAVE_ROUND */ diff --git a/contrib/tools/python3/src/Python/pystate.c b/contrib/tools/python3/src/Python/pystate.c deleted file mode 100644 index df98eb11bb0..00000000000 --- a/contrib/tools/python3/src/Python/pystate.c +++ /dev/null @@ -1,1977 +0,0 @@ - -/* Thread and interpreter state structures and their interfaces */ - -#include "Python.h" -#include "pycore_ceval.h" -#include "pycore_initconfig.h" -#include "pycore_object.h" // _PyType_InitCache() -#include "pycore_pyerrors.h" -#include "pycore_pylifecycle.h" -#include "pycore_pymem.h" // _PyMem_SetDefaultAllocator() -#include "pycore_pystate.h" // _PyThreadState_GET() -#include "pycore_sysmodule.h" - -/* -------------------------------------------------------------------------- -CAUTION - -Always use PyMem_RawMalloc() and PyMem_RawFree() directly in this file. A -number of these functions are advertised as safe to call when the GIL isn't -held, and in a debug build Python redirects (e.g.) PyMem_NEW (etc) to Python's -debugging obmalloc functions. Those aren't thread-safe (they rely on the GIL -to avoid the expense of doing their own locking). --------------------------------------------------------------------------- */ - -#ifdef HAVE_DLOPEN -#ifdef HAVE_DLFCN_H -#include <dlfcn.h> -#endif -#if !HAVE_DECL_RTLD_LAZY -#define RTLD_LAZY 1 -#endif -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#define _PyRuntimeGILState_GetThreadState(gilstate) \ - ((PyThreadState*)_Py_atomic_load_relaxed(&(gilstate)->tstate_current)) -#define _PyRuntimeGILState_SetThreadState(gilstate, value) \ - _Py_atomic_store_relaxed(&(gilstate)->tstate_current, \ - (uintptr_t)(value)) - -/* Forward declarations */ -static PyThreadState *_PyGILState_GetThisThreadState(struct _gilstate_runtime_state *gilstate); -static void _PyThreadState_Delete(PyThreadState *tstate, int check_current); - - -static PyStatus -_PyRuntimeState_Init_impl(_PyRuntimeState *runtime) -{ - /* We preserve the hook across init, because there is - currently no public API to set it between runtime - initialization and interpreter initialization. */ - void *open_code_hook = runtime->open_code_hook; - void *open_code_userdata = runtime->open_code_userdata; - _Py_AuditHookEntry *audit_hook_head = runtime->audit_hook_head; - // bpo-42882: Preserve next_index value if Py_Initialize()/Py_Finalize() - // is called multiple times. - Py_ssize_t unicode_next_index = runtime->unicode_ids.next_index; - - memset(runtime, 0, sizeof(*runtime)); - - runtime->open_code_hook = open_code_hook; - runtime->open_code_userdata = open_code_userdata; - runtime->audit_hook_head = audit_hook_head; - - _PyEval_InitRuntimeState(&runtime->ceval); - - PyPreConfig_InitPythonConfig(&runtime->preconfig); - - runtime->gilstate.check_enabled = 1; - - /* A TSS key must be initialized with Py_tss_NEEDS_INIT - in accordance with the specification. */ - Py_tss_t initial = Py_tss_NEEDS_INIT; - runtime->gilstate.autoTSSkey = initial; - - runtime->interpreters.mutex = PyThread_allocate_lock(); - if (runtime->interpreters.mutex == NULL) { - return _PyStatus_NO_MEMORY(); - } - runtime->interpreters.next_id = -1; - - runtime->xidregistry.mutex = PyThread_allocate_lock(); - if (runtime->xidregistry.mutex == NULL) { - return _PyStatus_NO_MEMORY(); - } - - // Set it to the ID of the main thread of the main interpreter. - runtime->main_thread = PyThread_get_thread_ident(); - - runtime->unicode_ids.lock = PyThread_allocate_lock(); - if (runtime->unicode_ids.lock == NULL) { - return _PyStatus_NO_MEMORY(); - } - runtime->unicode_ids.next_index = unicode_next_index; - - return _PyStatus_OK(); -} - -PyStatus -_PyRuntimeState_Init(_PyRuntimeState *runtime) -{ - /* Force default allocator, since _PyRuntimeState_Fini() must - use the same allocator than this function. */ - PyMemAllocatorEx old_alloc; - _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - - PyStatus status = _PyRuntimeState_Init_impl(runtime); - - PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - return status; -} - -void -_PyRuntimeState_Fini(_PyRuntimeState *runtime) -{ - /* Force the allocator used by _PyRuntimeState_Init(). */ - PyMemAllocatorEx old_alloc; - _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); -#define FREE_LOCK(LOCK) \ - if (LOCK != NULL) { \ - PyThread_free_lock(LOCK); \ - LOCK = NULL; \ - } - - FREE_LOCK(runtime->interpreters.mutex); - FREE_LOCK(runtime->xidregistry.mutex); - FREE_LOCK(runtime->unicode_ids.lock); - -#undef FREE_LOCK - PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); -} - -#ifdef HAVE_FORK -/* This function is called from PyOS_AfterFork_Child to ensure that - newly created child processes do not share locks with the parent. */ -PyStatus -_PyRuntimeState_ReInitThreads(_PyRuntimeState *runtime) -{ - // This was initially set in _PyRuntimeState_Init(). - runtime->main_thread = PyThread_get_thread_ident(); - - /* Force default allocator, since _PyRuntimeState_Fini() must - use the same allocator than this function. */ - PyMemAllocatorEx old_alloc; - _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - - int reinit_interp = _PyThread_at_fork_reinit(&runtime->interpreters.mutex); - int reinit_xidregistry = _PyThread_at_fork_reinit(&runtime->xidregistry.mutex); - int reinit_unicode_ids = _PyThread_at_fork_reinit(&runtime->unicode_ids.lock); - - PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - - /* bpo-42540: id_mutex is freed by _PyInterpreterState_Delete, which does - * not force the default allocator. */ - int reinit_main_id = _PyThread_at_fork_reinit(&runtime->interpreters.main->id_mutex); - - if (reinit_interp < 0 - || reinit_main_id < 0 - || reinit_xidregistry < 0 - || reinit_unicode_ids < 0) - { - return _PyStatus_ERR("Failed to reinitialize runtime locks"); - - } - return _PyStatus_OK(); -} -#endif - -#define HEAD_LOCK(runtime) \ - PyThread_acquire_lock((runtime)->interpreters.mutex, WAIT_LOCK) -#define HEAD_UNLOCK(runtime) \ - PyThread_release_lock((runtime)->interpreters.mutex) - -/* Forward declaration */ -static void _PyGILState_NoteThreadState( - struct _gilstate_runtime_state *gilstate, PyThreadState* tstate); - -PyStatus -_PyInterpreterState_Enable(_PyRuntimeState *runtime) -{ - struct pyinterpreters *interpreters = &runtime->interpreters; - interpreters->next_id = 0; - - /* Py_Finalize() calls _PyRuntimeState_Fini() which clears the mutex. - Create a new mutex if needed. */ - if (interpreters->mutex == NULL) { - /* Force default allocator, since _PyRuntimeState_Fini() must - use the same allocator than this function. */ - PyMemAllocatorEx old_alloc; - _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - - interpreters->mutex = PyThread_allocate_lock(); - - PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - - if (interpreters->mutex == NULL) { - return _PyStatus_ERR("Can't initialize threads for interpreter"); - } - } - - return _PyStatus_OK(); -} - -PyInterpreterState * -PyInterpreterState_New(void) -{ - PyThreadState *tstate = _PyThreadState_GET(); - /* tstate is NULL when Py_InitializeFromConfig() calls - PyInterpreterState_New() to create the main interpreter. */ - if (_PySys_Audit(tstate, "cpython.PyInterpreterState_New", NULL) < 0) { - return NULL; - } - - PyInterpreterState *interp = PyMem_RawCalloc(1, sizeof(PyInterpreterState)); - if (interp == NULL) { - return NULL; - } - - interp->id_refcount = -1; - - /* Don't get runtime from tstate since tstate can be NULL */ - _PyRuntimeState *runtime = &_PyRuntime; - interp->runtime = runtime; - - if (_PyEval_InitState(&interp->ceval) < 0) { - goto out_of_memory; - } - - _PyGC_InitState(&interp->gc); - PyConfig_InitPythonConfig(&interp->config); - _PyType_InitCache(interp); - - interp->eval_frame = _PyEval_EvalFrameDefault; -#ifdef HAVE_DLOPEN -#if HAVE_DECL_RTLD_NOW - interp->dlopenflags = RTLD_NOW; -#else - interp->dlopenflags = RTLD_LAZY; -#endif -#endif - - struct pyinterpreters *interpreters = &runtime->interpreters; - - HEAD_LOCK(runtime); - if (interpreters->next_id < 0) { - /* overflow or Py_Initialize() not called! */ - if (tstate != NULL) { - _PyErr_SetString(tstate, PyExc_RuntimeError, - "failed to get an interpreter ID"); - } - PyMem_RawFree(interp); - interp = NULL; - } - else { - interp->id = interpreters->next_id; - interpreters->next_id += 1; - interp->next = interpreters->head; - if (interpreters->main == NULL) { - interpreters->main = interp; - } - interpreters->head = interp; - } - HEAD_UNLOCK(runtime); - - if (interp == NULL) { - return NULL; - } - - interp->tstate_next_unique_id = 0; - - interp->audit_hooks = NULL; - - return interp; - -out_of_memory: - if (tstate != NULL) { - _PyErr_NoMemory(tstate); - } - - PyMem_RawFree(interp); - return NULL; -} - - -static void -interpreter_clear(PyInterpreterState *interp, PyThreadState *tstate) -{ - _PyRuntimeState *runtime = interp->runtime; - - if (_PySys_Audit(tstate, "cpython.PyInterpreterState_Clear", NULL) < 0) { - _PyErr_Clear(tstate); - } - - HEAD_LOCK(runtime); - for (PyThreadState *p = interp->tstate_head; p != NULL; p = p->next) { - PyThreadState_Clear(p); - } - HEAD_UNLOCK(runtime); - - Py_CLEAR(interp->audit_hooks); - - PyConfig_Clear(&interp->config); - Py_CLEAR(interp->codec_search_path); - Py_CLEAR(interp->codec_search_cache); - Py_CLEAR(interp->codec_error_registry); - Py_CLEAR(interp->modules); - Py_CLEAR(interp->modules_by_index); - Py_CLEAR(interp->builtins_copy); - Py_CLEAR(interp->importlib); - Py_CLEAR(interp->import_func); - Py_CLEAR(interp->dict); -#ifdef HAVE_FORK - Py_CLEAR(interp->before_forkers); - Py_CLEAR(interp->after_forkers_parent); - Py_CLEAR(interp->after_forkers_child); -#endif - - _PyAST_Fini(interp); - _PyWarnings_Fini(interp); - _PyAtExit_Fini(interp); - - // All Python types must be destroyed before the last GC collection. Python - // types create a reference cycle to themselves in their in their - // PyTypeObject.tp_mro member (the tuple contains the type). - - /* Last garbage collection on this interpreter */ - _PyGC_CollectNoFail(tstate); - _PyGC_Fini(interp); - - /* We don't clear sysdict and builtins until the end of this function. - Because clearing other attributes can execute arbitrary Python code - which requires sysdict and builtins. */ - PyDict_Clear(interp->sysdict); - PyDict_Clear(interp->builtins); - Py_CLEAR(interp->sysdict); - Py_CLEAR(interp->builtins); - - // XXX Once we have one allocator per interpreter (i.e. - // per-interpreter GC) we must ensure that all of the interpreter's - // objects have been cleaned up at the point. -} - - -void -PyInterpreterState_Clear(PyInterpreterState *interp) -{ - // Use the current Python thread state to call audit hooks and to collect - // garbage. It can be different than the current Python thread state - // of 'interp'. - PyThreadState *current_tstate = _PyThreadState_GET(); - - interpreter_clear(interp, current_tstate); -} - - -void -_PyInterpreterState_Clear(PyThreadState *tstate) -{ - interpreter_clear(tstate->interp, tstate); -} - - -static void -zapthreads(PyInterpreterState *interp, int check_current) -{ - PyThreadState *tstate; - /* No need to lock the mutex here because this should only happen - when the threads are all really dead (XXX famous last words). */ - while ((tstate = interp->tstate_head) != NULL) { - _PyThreadState_Delete(tstate, check_current); - } -} - - -void -PyInterpreterState_Delete(PyInterpreterState *interp) -{ - _PyRuntimeState *runtime = interp->runtime; - struct pyinterpreters *interpreters = &runtime->interpreters; - zapthreads(interp, 0); - - _PyEval_FiniState(&interp->ceval); - - /* Delete current thread. After this, many C API calls become crashy. */ - _PyThreadState_Swap(&runtime->gilstate, NULL); - - HEAD_LOCK(runtime); - PyInterpreterState **p; - for (p = &interpreters->head; ; p = &(*p)->next) { - if (*p == NULL) { - Py_FatalError("NULL interpreter"); - } - if (*p == interp) { - break; - } - } - if (interp->tstate_head != NULL) { - Py_FatalError("remaining threads"); - } - *p = interp->next; - - if (interpreters->main == interp) { - interpreters->main = NULL; - if (interpreters->head != NULL) { - Py_FatalError("remaining subinterpreters"); - } - } - HEAD_UNLOCK(runtime); - - if (interp->id_mutex != NULL) { - PyThread_free_lock(interp->id_mutex); - } - PyMem_RawFree(interp); -} - - -#ifdef HAVE_FORK -/* - * Delete all interpreter states except the main interpreter. If there - * is a current interpreter state, it *must* be the main interpreter. - */ -PyStatus -_PyInterpreterState_DeleteExceptMain(_PyRuntimeState *runtime) -{ - struct _gilstate_runtime_state *gilstate = &runtime->gilstate; - struct pyinterpreters *interpreters = &runtime->interpreters; - - PyThreadState *tstate = _PyThreadState_Swap(gilstate, NULL); - if (tstate != NULL && tstate->interp != interpreters->main) { - return _PyStatus_ERR("not main interpreter"); - } - - HEAD_LOCK(runtime); - PyInterpreterState *interp = interpreters->head; - interpreters->head = NULL; - while (interp != NULL) { - if (interp == interpreters->main) { - interpreters->main->next = NULL; - interpreters->head = interp; - interp = interp->next; - continue; - } - - PyInterpreterState_Clear(interp); // XXX must activate? - zapthreads(interp, 1); - if (interp->id_mutex != NULL) { - PyThread_free_lock(interp->id_mutex); - } - PyInterpreterState *prev_interp = interp; - interp = interp->next; - PyMem_RawFree(prev_interp); - } - HEAD_UNLOCK(runtime); - - if (interpreters->head == NULL) { - return _PyStatus_ERR("missing main interpreter"); - } - _PyThreadState_Swap(gilstate, tstate); - return _PyStatus_OK(); -} -#endif - - -PyInterpreterState * -PyInterpreterState_Get(void) -{ - PyThreadState *tstate = _PyThreadState_GET(); - _Py_EnsureTstateNotNULL(tstate); - PyInterpreterState *interp = tstate->interp; - if (interp == NULL) { - Py_FatalError("no current interpreter"); - } - return interp; -} - - -int64_t -PyInterpreterState_GetID(PyInterpreterState *interp) -{ - if (interp == NULL) { - PyErr_SetString(PyExc_RuntimeError, "no interpreter provided"); - return -1; - } - return interp->id; -} - - -static PyInterpreterState * -interp_look_up_id(_PyRuntimeState *runtime, int64_t requested_id) -{ - PyInterpreterState *interp = runtime->interpreters.head; - while (interp != NULL) { - int64_t id = PyInterpreterState_GetID(interp); - if (id < 0) { - return NULL; - } - if (requested_id == id) { - return interp; - } - interp = PyInterpreterState_Next(interp); - } - return NULL; -} - -PyInterpreterState * -_PyInterpreterState_LookUpID(int64_t requested_id) -{ - PyInterpreterState *interp = NULL; - if (requested_id >= 0) { - _PyRuntimeState *runtime = &_PyRuntime; - HEAD_LOCK(runtime); - interp = interp_look_up_id(runtime, requested_id); - HEAD_UNLOCK(runtime); - } - if (interp == NULL && !PyErr_Occurred()) { - PyErr_Format(PyExc_RuntimeError, - "unrecognized interpreter ID %lld", requested_id); - } - return interp; -} - - -int -_PyInterpreterState_IDInitref(PyInterpreterState *interp) -{ - if (interp->id_mutex != NULL) { - return 0; - } - interp->id_mutex = PyThread_allocate_lock(); - if (interp->id_mutex == NULL) { - PyErr_SetString(PyExc_RuntimeError, - "failed to create init interpreter ID mutex"); - return -1; - } - interp->id_refcount = 0; - return 0; -} - - -int -_PyInterpreterState_IDIncref(PyInterpreterState *interp) -{ - if (_PyInterpreterState_IDInitref(interp) < 0) { - return -1; - } - - PyThread_acquire_lock(interp->id_mutex, WAIT_LOCK); - interp->id_refcount += 1; - PyThread_release_lock(interp->id_mutex); - return 0; -} - - -void -_PyInterpreterState_IDDecref(PyInterpreterState *interp) -{ - assert(interp->id_mutex != NULL); - - struct _gilstate_runtime_state *gilstate = &_PyRuntime.gilstate; - PyThread_acquire_lock(interp->id_mutex, WAIT_LOCK); - assert(interp->id_refcount != 0); - interp->id_refcount -= 1; - int64_t refcount = interp->id_refcount; - PyThread_release_lock(interp->id_mutex); - - if (refcount == 0 && interp->requires_idref) { - // XXX Using the "head" thread isn't strictly correct. - PyThreadState *tstate = PyInterpreterState_ThreadHead(interp); - // XXX Possible GILState issues? - PyThreadState *save_tstate = _PyThreadState_Swap(gilstate, tstate); - Py_EndInterpreter(tstate); - _PyThreadState_Swap(gilstate, save_tstate); - } -} - -int -_PyInterpreterState_RequiresIDRef(PyInterpreterState *interp) -{ - return interp->requires_idref; -} - -void -_PyInterpreterState_RequireIDRef(PyInterpreterState *interp, int required) -{ - interp->requires_idref = required ? 1 : 0; -} - -PyObject * -_PyInterpreterState_GetMainModule(PyInterpreterState *interp) -{ - if (interp->modules == NULL) { - PyErr_SetString(PyExc_RuntimeError, "interpreter not initialized"); - return NULL; - } - return PyMapping_GetItemString(interp->modules, "__main__"); -} - -PyObject * -PyInterpreterState_GetDict(PyInterpreterState *interp) -{ - if (interp->dict == NULL) { - interp->dict = PyDict_New(); - if (interp->dict == NULL) { - PyErr_Clear(); - } - } - /* Returning NULL means no per-interpreter dict is available. */ - return interp->dict; -} - -static PyThreadState * -new_threadstate(PyInterpreterState *interp, int init) -{ - _PyRuntimeState *runtime = interp->runtime; - PyThreadState *tstate = (PyThreadState *)PyMem_RawMalloc(sizeof(PyThreadState)); - if (tstate == NULL) { - return NULL; - } - - tstate->interp = interp; - - tstate->frame = NULL; - tstate->recursion_depth = 0; - tstate->recursion_headroom = 0; - tstate->stackcheck_counter = 0; - tstate->tracing = 0; - tstate->root_cframe.use_tracing = 0; - tstate->cframe = &tstate->root_cframe; - tstate->gilstate_counter = 0; - tstate->async_exc = NULL; - tstate->thread_id = PyThread_get_thread_ident(); - - tstate->dict = NULL; - - tstate->curexc_type = NULL; - tstate->curexc_value = NULL; - tstate->curexc_traceback = NULL; - - tstate->exc_state.exc_type = NULL; - tstate->exc_state.exc_value = NULL; - tstate->exc_state.exc_traceback = NULL; - tstate->exc_state.previous_item = NULL; - tstate->exc_info = &tstate->exc_state; - - tstate->c_profilefunc = NULL; - tstate->c_tracefunc = NULL; - tstate->c_profileobj = NULL; - tstate->c_traceobj = NULL; - - tstate->trash_delete_nesting = 0; - tstate->trash_delete_later = NULL; - tstate->on_delete = NULL; - tstate->on_delete_data = NULL; - - tstate->coroutine_origin_tracking_depth = 0; - - tstate->async_gen_firstiter = NULL; - tstate->async_gen_finalizer = NULL; - - tstate->context = NULL; - tstate->context_ver = 1; - - if (init) { - _PyThreadState_Init(tstate); - } - - HEAD_LOCK(runtime); - tstate->id = ++interp->tstate_next_unique_id; - tstate->prev = NULL; - tstate->next = interp->tstate_head; - if (tstate->next) - tstate->next->prev = tstate; - interp->tstate_head = tstate; - HEAD_UNLOCK(runtime); - - return tstate; -} - -PyThreadState * -PyThreadState_New(PyInterpreterState *interp) -{ - return new_threadstate(interp, 1); -} - -PyThreadState * -_PyThreadState_Prealloc(PyInterpreterState *interp) -{ - return new_threadstate(interp, 0); -} - -void -_PyThreadState_Init(PyThreadState *tstate) -{ - _PyGILState_NoteThreadState(&tstate->interp->runtime->gilstate, tstate); -} - -PyObject* -PyState_FindModule(struct PyModuleDef* module) -{ - Py_ssize_t index = module->m_base.m_index; - PyInterpreterState *state = _PyInterpreterState_GET(); - PyObject *res; - if (module->m_slots) { - return NULL; - } - if (index == 0) - return NULL; - if (state->modules_by_index == NULL) - return NULL; - if (index >= PyList_GET_SIZE(state->modules_by_index)) - return NULL; - res = PyList_GET_ITEM(state->modules_by_index, index); - return res==Py_None ? NULL : res; -} - -int -_PyState_AddModule(PyThreadState *tstate, PyObject* module, struct PyModuleDef* def) -{ - if (!def) { - assert(_PyErr_Occurred(tstate)); - return -1; - } - if (def->m_slots) { - _PyErr_SetString(tstate, - PyExc_SystemError, - "PyState_AddModule called on module with slots"); - return -1; - } - - PyInterpreterState *interp = tstate->interp; - if (!interp->modules_by_index) { - interp->modules_by_index = PyList_New(0); - if (!interp->modules_by_index) { - return -1; - } - } - - while (PyList_GET_SIZE(interp->modules_by_index) <= def->m_base.m_index) { - if (PyList_Append(interp->modules_by_index, Py_None) < 0) { - return -1; - } - } - - Py_INCREF(module); - return PyList_SetItem(interp->modules_by_index, - def->m_base.m_index, module); -} - -int -PyState_AddModule(PyObject* module, struct PyModuleDef* def) -{ - if (!def) { - Py_FatalError("module definition is NULL"); - return -1; - } - - PyThreadState *tstate = _PyThreadState_GET(); - PyInterpreterState *interp = tstate->interp; - Py_ssize_t index = def->m_base.m_index; - if (interp->modules_by_index && - index < PyList_GET_SIZE(interp->modules_by_index) && - module == PyList_GET_ITEM(interp->modules_by_index, index)) - { - _Py_FatalErrorFormat(__func__, "module %p already added", module); - return -1; - } - return _PyState_AddModule(tstate, module, def); -} - -int -PyState_RemoveModule(struct PyModuleDef* def) -{ - PyThreadState *tstate = _PyThreadState_GET(); - PyInterpreterState *interp = tstate->interp; - - if (def->m_slots) { - _PyErr_SetString(tstate, - PyExc_SystemError, - "PyState_RemoveModule called on module with slots"); - return -1; - } - - Py_ssize_t index = def->m_base.m_index; - if (index == 0) { - Py_FatalError("invalid module index"); - } - if (interp->modules_by_index == NULL) { - Py_FatalError("Interpreters module-list not accessible."); - } - if (index > PyList_GET_SIZE(interp->modules_by_index)) { - Py_FatalError("Module index out of bounds."); - } - - Py_INCREF(Py_None); - return PyList_SetItem(interp->modules_by_index, index, Py_None); -} - -// Used by finalize_modules() -void -_PyInterpreterState_ClearModules(PyInterpreterState *interp) -{ - if (!interp->modules_by_index) { - return; - } - - Py_ssize_t i; - for (i = 0; i < PyList_GET_SIZE(interp->modules_by_index); i++) { - PyObject *m = PyList_GET_ITEM(interp->modules_by_index, i); - if (PyModule_Check(m)) { - /* cleanup the saved copy of module dicts */ - PyModuleDef *md = PyModule_GetDef(m); - if (md) { - Py_CLEAR(md->m_base.m_copy); - } - } - } - - /* Setting modules_by_index to NULL could be dangerous, so we - clear the list instead. */ - if (PyList_SetSlice(interp->modules_by_index, - 0, PyList_GET_SIZE(interp->modules_by_index), - NULL)) { - PyErr_WriteUnraisable(interp->modules_by_index); - } -} - -void -PyThreadState_Clear(PyThreadState *tstate) -{ - int verbose = _PyInterpreterState_GetConfig(tstate->interp)->verbose; - - if (verbose && tstate->frame != NULL) { - /* bpo-20526: After the main thread calls - _PyRuntimeState_SetFinalizing() in Py_FinalizeEx(), threads must - exit when trying to take the GIL. If a thread exit in the middle of - _PyEval_EvalFrameDefault(), tstate->frame is not reset to its - previous value. It is more likely with daemon threads, but it can - happen with regular threads if threading._shutdown() fails - (ex: interrupted by CTRL+C). */ - fprintf(stderr, - "PyThreadState_Clear: warning: thread still has a frame\n"); - } - - /* Don't clear tstate->frame: it is a borrowed reference */ - - Py_CLEAR(tstate->dict); - Py_CLEAR(tstate->async_exc); - - Py_CLEAR(tstate->curexc_type); - Py_CLEAR(tstate->curexc_value); - Py_CLEAR(tstate->curexc_traceback); - - Py_CLEAR(tstate->exc_state.exc_type); - Py_CLEAR(tstate->exc_state.exc_value); - Py_CLEAR(tstate->exc_state.exc_traceback); - - /* The stack of exception states should contain just this thread. */ - if (verbose && tstate->exc_info != &tstate->exc_state) { - fprintf(stderr, - "PyThreadState_Clear: warning: thread still has a generator\n"); - } - - tstate->c_profilefunc = NULL; - tstate->c_tracefunc = NULL; - Py_CLEAR(tstate->c_profileobj); - Py_CLEAR(tstate->c_traceobj); - - Py_CLEAR(tstate->async_gen_firstiter); - Py_CLEAR(tstate->async_gen_finalizer); - - Py_CLEAR(tstate->context); - - if (tstate->on_delete != NULL) { - tstate->on_delete(tstate->on_delete_data); - } -} - - -/* Common code for PyThreadState_Delete() and PyThreadState_DeleteCurrent() */ -static void -tstate_delete_common(PyThreadState *tstate, - struct _gilstate_runtime_state *gilstate) -{ - _Py_EnsureTstateNotNULL(tstate); - PyInterpreterState *interp = tstate->interp; - if (interp == NULL) { - Py_FatalError("NULL interpreter"); - } - _PyRuntimeState *runtime = interp->runtime; - - HEAD_LOCK(runtime); - if (tstate->prev) { - tstate->prev->next = tstate->next; - } - else { - interp->tstate_head = tstate->next; - } - if (tstate->next) { - tstate->next->prev = tstate->prev; - } - HEAD_UNLOCK(runtime); - - if (gilstate->autoInterpreterState && - PyThread_tss_get(&gilstate->autoTSSkey) == tstate) - { - PyThread_tss_set(&gilstate->autoTSSkey, NULL); - } -} - - -static void -_PyThreadState_Delete(PyThreadState *tstate, int check_current) -{ - struct _gilstate_runtime_state *gilstate = &tstate->interp->runtime->gilstate; - if (check_current) { - if (tstate == _PyRuntimeGILState_GetThreadState(gilstate)) { - _Py_FatalErrorFormat(__func__, "tstate %p is still current", tstate); - } - } - tstate_delete_common(tstate, gilstate); - PyMem_RawFree(tstate); -} - - -void -PyThreadState_Delete(PyThreadState *tstate) -{ - _PyThreadState_Delete(tstate, 1); -} - - -void -_PyThreadState_DeleteCurrent(PyThreadState *tstate) -{ - _Py_EnsureTstateNotNULL(tstate); - struct _gilstate_runtime_state *gilstate = &tstate->interp->runtime->gilstate; - tstate_delete_common(tstate, gilstate); - _PyRuntimeGILState_SetThreadState(gilstate, NULL); - _PyEval_ReleaseLock(tstate); - PyMem_RawFree(tstate); -} - -void -PyThreadState_DeleteCurrent(void) -{ - struct _gilstate_runtime_state *gilstate = &_PyRuntime.gilstate; - PyThreadState *tstate = _PyRuntimeGILState_GetThreadState(gilstate); - _PyThreadState_DeleteCurrent(tstate); -} - - -/* - * Delete all thread states except the one passed as argument. - * Note that, if there is a current thread state, it *must* be the one - * passed as argument. Also, this won't touch any other interpreters - * than the current one, since we don't know which thread state should - * be kept in those other interpreters. - */ -void -_PyThreadState_DeleteExcept(_PyRuntimeState *runtime, PyThreadState *tstate) -{ - PyInterpreterState *interp = tstate->interp; - - HEAD_LOCK(runtime); - /* Remove all thread states, except tstate, from the linked list of - thread states. This will allow calling PyThreadState_Clear() - without holding the lock. */ - PyThreadState *list = interp->tstate_head; - if (list == tstate) { - list = tstate->next; - } - if (tstate->prev) { - tstate->prev->next = tstate->next; - } - if (tstate->next) { - tstate->next->prev = tstate->prev; - } - tstate->prev = tstate->next = NULL; - interp->tstate_head = tstate; - HEAD_UNLOCK(runtime); - - /* Clear and deallocate all stale thread states. Even if this - executes Python code, we should be safe since it executes - in the current thread, not one of the stale threads. */ - PyThreadState *p, *next; - for (p = list; p; p = next) { - next = p->next; - PyThreadState_Clear(p); - PyMem_RawFree(p); - } -} - - -#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS -PyThreadState* -_PyThreadState_GetTSS(void) { - return PyThread_tss_get(&_PyRuntime.gilstate.autoTSSkey); -} -#endif - - -PyThreadState * -_PyThreadState_UncheckedGet(void) -{ - return _PyThreadState_GET(); -} - - -PyThreadState * -PyThreadState_Get(void) -{ - PyThreadState *tstate = _PyThreadState_GET(); - _Py_EnsureTstateNotNULL(tstate); - return tstate; -} - - -PyThreadState * -_PyThreadState_Swap(struct _gilstate_runtime_state *gilstate, PyThreadState *newts) -{ -#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS - PyThreadState *oldts = _PyThreadState_GetTSS(); -#else - PyThreadState *oldts = _PyRuntimeGILState_GetThreadState(gilstate); -#endif - - _PyRuntimeGILState_SetThreadState(gilstate, newts); - /* It should not be possible for more than one thread state - to be used for a thread. Check this the best we can in debug - builds. - */ -#if defined(Py_DEBUG) - if (newts) { - /* This can be called from PyEval_RestoreThread(). Similar - to it, we need to ensure errno doesn't change. - */ - int err = errno; - PyThreadState *check = _PyGILState_GetThisThreadState(gilstate); - if (check && check->interp == newts->interp && check != newts) - Py_FatalError("Invalid thread state for this thread"); - errno = err; - } -#endif -#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS - PyThread_tss_set(&gilstate->autoTSSkey, newts); -#endif - return oldts; -} - -PyThreadState * -PyThreadState_Swap(PyThreadState *newts) -{ - return _PyThreadState_Swap(&_PyRuntime.gilstate, newts); -} - -/* An extension mechanism to store arbitrary additional per-thread state. - PyThreadState_GetDict() returns a dictionary that can be used to hold such - state; the caller should pick a unique key and store its state there. If - PyThreadState_GetDict() returns NULL, an exception has *not* been raised - and the caller should assume no per-thread state is available. */ - -PyObject * -_PyThreadState_GetDict(PyThreadState *tstate) -{ - assert(tstate != NULL); - if (tstate->dict == NULL) { - tstate->dict = PyDict_New(); - if (tstate->dict == NULL) { - _PyErr_Clear(tstate); - } - } - return tstate->dict; -} - - -PyObject * -PyThreadState_GetDict(void) -{ - PyThreadState *tstate = _PyThreadState_GET(); - if (tstate == NULL) { - return NULL; - } - return _PyThreadState_GetDict(tstate); -} - - -PyInterpreterState * -PyThreadState_GetInterpreter(PyThreadState *tstate) -{ - assert(tstate != NULL); - return tstate->interp; -} - - -PyFrameObject* -PyThreadState_GetFrame(PyThreadState *tstate) -{ - assert(tstate != NULL); - PyFrameObject *frame = tstate->frame; - Py_XINCREF(frame); - return frame; -} - - -uint64_t -PyThreadState_GetID(PyThreadState *tstate) -{ - assert(tstate != NULL); - return tstate->id; -} - - -/* Asynchronously raise an exception in a thread. - Requested by Just van Rossum and Alex Martelli. - To prevent naive misuse, you must write your own extension - to call this, or use ctypes. Must be called with the GIL held. - Returns the number of tstates modified (normally 1, but 0 if `id` didn't - match any known thread id). Can be called with exc=NULL to clear an - existing async exception. This raises no exceptions. */ - -int -PyThreadState_SetAsyncExc(unsigned long id, PyObject *exc) -{ - _PyRuntimeState *runtime = &_PyRuntime; - PyInterpreterState *interp = _PyRuntimeState_GetThreadState(runtime)->interp; - - /* Although the GIL is held, a few C API functions can be called - * without the GIL held, and in particular some that create and - * destroy thread and interpreter states. Those can mutate the - * list of thread states we're traversing, so to prevent that we lock - * head_mutex for the duration. - */ - HEAD_LOCK(runtime); - for (PyThreadState *tstate = interp->tstate_head; tstate != NULL; tstate = tstate->next) { - if (tstate->thread_id != id) { - continue; - } - - /* Tricky: we need to decref the current value - * (if any) in tstate->async_exc, but that can in turn - * allow arbitrary Python code to run, including - * perhaps calls to this function. To prevent - * deadlock, we need to release head_mutex before - * the decref. - */ - PyObject *old_exc = tstate->async_exc; - Py_XINCREF(exc); - tstate->async_exc = exc; - HEAD_UNLOCK(runtime); - - Py_XDECREF(old_exc); - _PyEval_SignalAsyncExc(tstate->interp); - return 1; - } - HEAD_UNLOCK(runtime); - return 0; -} - - -/* Routines for advanced debuggers, requested by David Beazley. - Don't use unless you know what you are doing! */ - -PyInterpreterState * -PyInterpreterState_Head(void) -{ - return _PyRuntime.interpreters.head; -} - -PyInterpreterState * -PyInterpreterState_Main(void) -{ - return _PyRuntime.interpreters.main; -} - -PyInterpreterState * -PyInterpreterState_Next(PyInterpreterState *interp) { - return interp->next; -} - -PyThreadState * -PyInterpreterState_ThreadHead(PyInterpreterState *interp) { - return interp->tstate_head; -} - -PyThreadState * -PyThreadState_Next(PyThreadState *tstate) { - return tstate->next; -} - -/* The implementation of sys._current_frames(). This is intended to be - called with the GIL held, as it will be when called via - sys._current_frames(). It's possible it would work fine even without - the GIL held, but haven't thought enough about that. -*/ -PyObject * -_PyThread_CurrentFrames(void) -{ - PyThreadState *tstate = _PyThreadState_GET(); - if (_PySys_Audit(tstate, "sys._current_frames", NULL) < 0) { - return NULL; - } - - PyObject *result = PyDict_New(); - if (result == NULL) { - return NULL; - } - - /* for i in all interpreters: - * for t in all of i's thread states: - * if t's frame isn't NULL, map t's id to its frame - * Because these lists can mutate even when the GIL is held, we - * need to grab head_mutex for the duration. - */ - _PyRuntimeState *runtime = tstate->interp->runtime; - HEAD_LOCK(runtime); - PyInterpreterState *i; - for (i = runtime->interpreters.head; i != NULL; i = i->next) { - PyThreadState *t; - for (t = i->tstate_head; t != NULL; t = t->next) { - PyFrameObject *frame = t->frame; - if (frame == NULL) { - continue; - } - PyObject *id = PyLong_FromUnsignedLong(t->thread_id); - if (id == NULL) { - goto fail; - } - int stat = PyDict_SetItem(result, id, (PyObject *)frame); - Py_DECREF(id); - if (stat < 0) { - goto fail; - } - } - } - goto done; - -fail: - Py_CLEAR(result); - -done: - HEAD_UNLOCK(runtime); - return result; -} - -PyObject * -_PyThread_CurrentExceptions(void) -{ - PyThreadState *tstate = _PyThreadState_GET(); - - _Py_EnsureTstateNotNULL(tstate); - - if (_PySys_Audit(tstate, "sys._current_exceptions", NULL) < 0) { - return NULL; - } - - PyObject *result = PyDict_New(); - if (result == NULL) { - return NULL; - } - - /* for i in all interpreters: - * for t in all of i's thread states: - * if t's frame isn't NULL, map t's id to its frame - * Because these lists can mutate even when the GIL is held, we - * need to grab head_mutex for the duration. - */ - _PyRuntimeState *runtime = tstate->interp->runtime; - HEAD_LOCK(runtime); - PyInterpreterState *i; - for (i = runtime->interpreters.head; i != NULL; i = i->next) { - PyThreadState *t; - for (t = i->tstate_head; t != NULL; t = t->next) { - _PyErr_StackItem *err_info = _PyErr_GetTopmostException(t); - if (err_info == NULL) { - continue; - } - PyObject *id = PyLong_FromUnsignedLong(t->thread_id); - if (id == NULL) { - goto fail; - } - PyObject *exc_info = PyTuple_Pack( - 3, - err_info->exc_type != NULL ? err_info->exc_type : Py_None, - err_info->exc_value != NULL ? err_info->exc_value : Py_None, - err_info->exc_traceback != NULL ? err_info->exc_traceback : Py_None); - if (exc_info == NULL) { - Py_DECREF(id); - goto fail; - } - int stat = PyDict_SetItem(result, id, exc_info); - Py_DECREF(id); - Py_DECREF(exc_info); - if (stat < 0) { - goto fail; - } - } - } - goto done; - -fail: - Py_CLEAR(result); - -done: - HEAD_UNLOCK(runtime); - return result; -} - -/* Python "auto thread state" API. */ - -/* Keep this as a static, as it is not reliable! It can only - ever be compared to the state for the *current* thread. - * If not equal, then it doesn't matter that the actual - value may change immediately after comparison, as it can't - possibly change to the current thread's state. - * If equal, then the current thread holds the lock, so the value can't - change until we yield the lock. -*/ -static int -PyThreadState_IsCurrent(PyThreadState *tstate) -{ - /* Must be the tstate for this thread */ - struct _gilstate_runtime_state *gilstate = &_PyRuntime.gilstate; - assert(_PyGILState_GetThisThreadState(gilstate) == tstate); - return tstate == _PyRuntimeGILState_GetThreadState(gilstate); -} - -/* Internal initialization/finalization functions called by - Py_Initialize/Py_FinalizeEx -*/ -PyStatus -_PyGILState_Init(_PyRuntimeState *runtime) -{ - struct _gilstate_runtime_state *gilstate = &runtime->gilstate; - if (PyThread_tss_create(&gilstate->autoTSSkey) != 0) { - return _PyStatus_NO_MEMORY(); - } - // PyThreadState_New() calls _PyGILState_NoteThreadState() which does - // nothing before autoInterpreterState is set. - assert(gilstate->autoInterpreterState == NULL); - return _PyStatus_OK(); -} - - -PyStatus -_PyGILState_SetTstate(PyThreadState *tstate) -{ - if (!_Py_IsMainInterpreter(tstate->interp)) { - /* Currently, PyGILState is shared by all interpreters. The main - * interpreter is responsible to initialize it. */ - return _PyStatus_OK(); - } - - /* must init with valid states */ - assert(tstate != NULL); - assert(tstate->interp != NULL); - - struct _gilstate_runtime_state *gilstate = &tstate->interp->runtime->gilstate; - - gilstate->autoInterpreterState = tstate->interp; - assert(PyThread_tss_get(&gilstate->autoTSSkey) == NULL); - assert(tstate->gilstate_counter == 0); - - _PyGILState_NoteThreadState(gilstate, tstate); - return _PyStatus_OK(); -} - -PyInterpreterState * -_PyGILState_GetInterpreterStateUnsafe(void) -{ - return _PyRuntime.gilstate.autoInterpreterState; -} - -void -_PyGILState_Fini(PyInterpreterState *interp) -{ - struct _gilstate_runtime_state *gilstate = &interp->runtime->gilstate; - PyThread_tss_delete(&gilstate->autoTSSkey); - gilstate->autoInterpreterState = NULL; -} - -#ifdef HAVE_FORK -/* Reset the TSS key - called by PyOS_AfterFork_Child(). - * This should not be necessary, but some - buggy - pthread implementations - * don't reset TSS upon fork(), see issue #10517. - */ -PyStatus -_PyGILState_Reinit(_PyRuntimeState *runtime) -{ - struct _gilstate_runtime_state *gilstate = &runtime->gilstate; - PyThreadState *tstate = _PyGILState_GetThisThreadState(gilstate); - - PyThread_tss_delete(&gilstate->autoTSSkey); - if (PyThread_tss_create(&gilstate->autoTSSkey) != 0) { - return _PyStatus_NO_MEMORY(); - } - - /* If the thread had an associated auto thread state, reassociate it with - * the new key. */ - if (tstate && - PyThread_tss_set(&gilstate->autoTSSkey, (void *)tstate) != 0) - { - return _PyStatus_ERR("failed to set autoTSSkey"); - } - return _PyStatus_OK(); -} -#endif - -/* When a thread state is created for a thread by some mechanism other than - PyGILState_Ensure, it's important that the GILState machinery knows about - it so it doesn't try to create another thread state for the thread (this is - a better fix for SF bug #1010677 than the first one attempted). -*/ -static void -_PyGILState_NoteThreadState(struct _gilstate_runtime_state *gilstate, PyThreadState* tstate) -{ - /* If autoTSSkey isn't initialized, this must be the very first - threadstate created in Py_Initialize(). Don't do anything for now - (we'll be back here when _PyGILState_Init is called). */ - if (!gilstate->autoInterpreterState) { - return; - } - - /* Stick the thread state for this thread in thread specific storage. - - The only situation where you can legitimately have more than one - thread state for an OS level thread is when there are multiple - interpreters. - - You shouldn't really be using the PyGILState_ APIs anyway (see issues - #10915 and #15751). - - The first thread state created for that given OS level thread will - "win", which seems reasonable behaviour. - */ - if (PyThread_tss_get(&gilstate->autoTSSkey) == NULL) { - if ((PyThread_tss_set(&gilstate->autoTSSkey, (void *)tstate)) != 0) { - Py_FatalError("Couldn't create autoTSSkey mapping"); - } - } - - /* PyGILState_Release must not try to delete this thread state. */ - tstate->gilstate_counter = 1; -} - -/* The public functions */ -static PyThreadState * -_PyGILState_GetThisThreadState(struct _gilstate_runtime_state *gilstate) -{ - if (gilstate->autoInterpreterState == NULL) - return NULL; - return (PyThreadState *)PyThread_tss_get(&gilstate->autoTSSkey); -} - -PyThreadState * -PyGILState_GetThisThreadState(void) -{ - return _PyGILState_GetThisThreadState(&_PyRuntime.gilstate); -} - -int -PyGILState_Check(void) -{ - struct _gilstate_runtime_state *gilstate = &_PyRuntime.gilstate; - if (!gilstate->check_enabled) { - return 1; - } - - if (!PyThread_tss_is_created(&gilstate->autoTSSkey)) { - return 1; - } - - PyThreadState *tstate = _PyRuntimeGILState_GetThreadState(gilstate); - if (tstate == NULL) { - return 0; - } - - return (tstate == _PyGILState_GetThisThreadState(gilstate)); -} - -PyGILState_STATE -PyGILState_Ensure(void) -{ - _PyRuntimeState *runtime = &_PyRuntime; - struct _gilstate_runtime_state *gilstate = &runtime->gilstate; - - /* Note that we do not auto-init Python here - apart from - potential races with 2 threads auto-initializing, pep-311 - spells out other issues. Embedders are expected to have - called Py_Initialize(). */ - - /* Ensure that _PyEval_InitThreads() and _PyGILState_Init() have been - called by Py_Initialize() */ -#ifndef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS - assert(_PyEval_ThreadsInitialized(runtime)); -#endif - assert(gilstate->autoInterpreterState); - - PyThreadState *tcur = (PyThreadState *)PyThread_tss_get(&gilstate->autoTSSkey); - int current; - if (tcur == NULL) { - /* Create a new Python thread state for this thread */ - tcur = PyThreadState_New(gilstate->autoInterpreterState); - if (tcur == NULL) { - Py_FatalError("Couldn't create thread-state for new thread"); - } - - /* This is our thread state! We'll need to delete it in the - matching call to PyGILState_Release(). */ - tcur->gilstate_counter = 0; - current = 0; /* new thread state is never current */ - } - else { - current = PyThreadState_IsCurrent(tcur); - } - - if (current == 0) { - PyEval_RestoreThread(tcur); - } - - /* Update our counter in the thread-state - no need for locks: - - tcur will remain valid as we hold the GIL. - - the counter is safe as we are the only thread "allowed" - to modify this value - */ - ++tcur->gilstate_counter; - - return current ? PyGILState_LOCKED : PyGILState_UNLOCKED; -} - -void -PyGILState_Release(PyGILState_STATE oldstate) -{ - _PyRuntimeState *runtime = &_PyRuntime; - PyThreadState *tstate = PyThread_tss_get(&runtime->gilstate.autoTSSkey); - if (tstate == NULL) { - Py_FatalError("auto-releasing thread-state, " - "but no thread-state for this thread"); - } - - /* We must hold the GIL and have our thread state current */ - /* XXX - remove the check - the assert should be fine, - but while this is very new (April 2003), the extra check - by release-only users can't hurt. - */ - if (!PyThreadState_IsCurrent(tstate)) { - _Py_FatalErrorFormat(__func__, - "thread state %p must be current when releasing", - tstate); - } - assert(PyThreadState_IsCurrent(tstate)); - --tstate->gilstate_counter; - assert(tstate->gilstate_counter >= 0); /* illegal counter value */ - - /* If we're going to destroy this thread-state, we must - * clear it while the GIL is held, as destructors may run. - */ - if (tstate->gilstate_counter == 0) { - /* can't have been locked when we created it */ - assert(oldstate == PyGILState_UNLOCKED); - PyThreadState_Clear(tstate); - /* Delete the thread-state. Note this releases the GIL too! - * It's vital that the GIL be held here, to avoid shutdown - * races; see bugs 225673 and 1061968 (that nasty bug has a - * habit of coming back). - */ - assert(_PyRuntimeGILState_GetThreadState(&runtime->gilstate) == tstate); - _PyThreadState_DeleteCurrent(tstate); - } - /* Release the lock if necessary */ - else if (oldstate == PyGILState_UNLOCKED) - PyEval_SaveThread(); -} - - -/**************************/ -/* cross-interpreter data */ -/**************************/ - -/* cross-interpreter data */ - -crossinterpdatafunc _PyCrossInterpreterData_Lookup(PyObject *); - -/* This is a separate func from _PyCrossInterpreterData_Lookup in order - to keep the registry code separate. */ -static crossinterpdatafunc -_lookup_getdata(PyObject *obj) -{ - crossinterpdatafunc getdata = _PyCrossInterpreterData_Lookup(obj); - if (getdata == NULL && PyErr_Occurred() == 0) - PyErr_Format(PyExc_ValueError, - "%S does not support cross-interpreter data", obj); - return getdata; -} - -int -_PyObject_CheckCrossInterpreterData(PyObject *obj) -{ - crossinterpdatafunc getdata = _lookup_getdata(obj); - if (getdata == NULL) { - return -1; - } - return 0; -} - -static int -_check_xidata(PyThreadState *tstate, _PyCrossInterpreterData *data) -{ - // data->data can be anything, including NULL, so we don't check it. - - // data->obj may be NULL, so we don't check it. - - if (data->interp < 0) { - _PyErr_SetString(tstate, PyExc_SystemError, "missing interp"); - return -1; - } - - if (data->new_object == NULL) { - _PyErr_SetString(tstate, PyExc_SystemError, "missing new_object func"); - return -1; - } - - // data->free may be NULL, so we don't check it. - - return 0; -} - -int -_PyObject_GetCrossInterpreterData(PyObject *obj, _PyCrossInterpreterData *data) -{ - // PyThreadState_Get() aborts if tstate is NULL. - PyThreadState *tstate = PyThreadState_Get(); - PyInterpreterState *interp = tstate->interp; - - // Reset data before re-populating. - *data = (_PyCrossInterpreterData){0}; - data->free = PyMem_RawFree; // Set a default that may be overridden. - - // Call the "getdata" func for the object. - Py_INCREF(obj); - crossinterpdatafunc getdata = _lookup_getdata(obj); - if (getdata == NULL) { - Py_DECREF(obj); - return -1; - } - int res = getdata(obj, data); - Py_DECREF(obj); - if (res != 0) { - return -1; - } - - // Fill in the blanks and validate the result. - data->interp = interp->id; - if (_check_xidata(tstate, data) != 0) { - _PyCrossInterpreterData_Release(data); - return -1; - } - - return 0; -} - -static void -_release_xidata(void *arg) -{ - _PyCrossInterpreterData *data = (_PyCrossInterpreterData *)arg; - if (data->free != NULL) { - data->free(data->data); - } - Py_XDECREF(data->obj); -} - -static void -_call_in_interpreter(struct _gilstate_runtime_state *gilstate, - PyInterpreterState *interp, - void (*func)(void *), void *arg) -{ - /* We would use Py_AddPendingCall() if it weren't specific to the - * main interpreter (see bpo-33608). In the meantime we take a - * naive approach. - */ - PyThreadState *save_tstate = NULL; - if (interp != _PyRuntimeGILState_GetThreadState(gilstate)->interp) { - // XXX Using the "head" thread isn't strictly correct. - PyThreadState *tstate = PyInterpreterState_ThreadHead(interp); - // XXX Possible GILState issues? - save_tstate = _PyThreadState_Swap(gilstate, tstate); - } - - func(arg); - - // Switch back. - if (save_tstate != NULL) { - _PyThreadState_Swap(gilstate, save_tstate); - } -} - -void -_PyCrossInterpreterData_Release(_PyCrossInterpreterData *data) -{ - if (data->data == NULL && data->obj == NULL) { - // Nothing to release! - return; - } - - // Switch to the original interpreter. - PyInterpreterState *interp = _PyInterpreterState_LookUpID(data->interp); - if (interp == NULL) { - // The interpreter was already destroyed. - if (data->free != NULL) { - // XXX Someone leaked some memory... - } - return; - } - - // "Release" the data and/or the object. - struct _gilstate_runtime_state *gilstate = &_PyRuntime.gilstate; - _call_in_interpreter(gilstate, interp, _release_xidata, data); -} - -PyObject * -_PyCrossInterpreterData_NewObject(_PyCrossInterpreterData *data) -{ - return data->new_object(data); -} - -/* registry of {type -> crossinterpdatafunc} */ - -/* For now we use a global registry of shareable classes. An - alternative would be to add a tp_* slot for a class's - crossinterpdatafunc. It would be simpler and more efficient. */ - -static int -_register_xidata(struct _xidregistry *xidregistry, PyTypeObject *cls, - crossinterpdatafunc getdata) -{ - // Note that we effectively replace already registered classes - // rather than failing. - struct _xidregitem *newhead = PyMem_RawMalloc(sizeof(struct _xidregitem)); - if (newhead == NULL) - return -1; - newhead->cls = cls; - newhead->getdata = getdata; - newhead->next = xidregistry->head; - xidregistry->head = newhead; - return 0; -} - -static void _register_builtins_for_crossinterpreter_data(struct _xidregistry *xidregistry); - -int -_PyCrossInterpreterData_RegisterClass(PyTypeObject *cls, - crossinterpdatafunc getdata) -{ - if (!PyType_Check(cls)) { - PyErr_Format(PyExc_ValueError, "only classes may be registered"); - return -1; - } - if (getdata == NULL) { - PyErr_Format(PyExc_ValueError, "missing 'getdata' func"); - return -1; - } - - // Make sure the class isn't ever deallocated. - Py_INCREF((PyObject *)cls); - - struct _xidregistry *xidregistry = &_PyRuntime.xidregistry ; - PyThread_acquire_lock(xidregistry->mutex, WAIT_LOCK); - if (xidregistry->head == NULL) { - _register_builtins_for_crossinterpreter_data(xidregistry); - } - int res = _register_xidata(xidregistry, cls, getdata); - PyThread_release_lock(xidregistry->mutex); - return res; -} - -/* Cross-interpreter objects are looked up by exact match on the class. - We can reassess this policy when we move from a global registry to a - tp_* slot. */ - -crossinterpdatafunc -_PyCrossInterpreterData_Lookup(PyObject *obj) -{ - struct _xidregistry *xidregistry = &_PyRuntime.xidregistry ; - PyObject *cls = PyObject_Type(obj); - crossinterpdatafunc getdata = NULL; - PyThread_acquire_lock(xidregistry->mutex, WAIT_LOCK); - struct _xidregitem *cur = xidregistry->head; - if (cur == NULL) { - _register_builtins_for_crossinterpreter_data(xidregistry); - cur = xidregistry->head; - } - for(; cur != NULL; cur = cur->next) { - if (cur->cls == (PyTypeObject *)cls) { - getdata = cur->getdata; - break; - } - } - Py_DECREF(cls); - PyThread_release_lock(xidregistry->mutex); - return getdata; -} - -/* cross-interpreter data for builtin types */ - -struct _shared_bytes_data { - char *bytes; - Py_ssize_t len; -}; - -static PyObject * -_new_bytes_object(_PyCrossInterpreterData *data) -{ - struct _shared_bytes_data *shared = (struct _shared_bytes_data *)(data->data); - return PyBytes_FromStringAndSize(shared->bytes, shared->len); -} - -static int -_bytes_shared(PyObject *obj, _PyCrossInterpreterData *data) -{ - struct _shared_bytes_data *shared = PyMem_NEW(struct _shared_bytes_data, 1); - if (PyBytes_AsStringAndSize(obj, &shared->bytes, &shared->len) < 0) { - return -1; - } - data->data = (void *)shared; - Py_INCREF(obj); - data->obj = obj; // Will be "released" (decref'ed) when data released. - data->new_object = _new_bytes_object; - data->free = PyMem_Free; - return 0; -} - -struct _shared_str_data { - int kind; - const void *buffer; - Py_ssize_t len; -}; - -static PyObject * -_new_str_object(_PyCrossInterpreterData *data) -{ - struct _shared_str_data *shared = (struct _shared_str_data *)(data->data); - return PyUnicode_FromKindAndData(shared->kind, shared->buffer, shared->len); -} - -static int -_str_shared(PyObject *obj, _PyCrossInterpreterData *data) -{ - struct _shared_str_data *shared = PyMem_NEW(struct _shared_str_data, 1); - shared->kind = PyUnicode_KIND(obj); - shared->buffer = PyUnicode_DATA(obj); - shared->len = PyUnicode_GET_LENGTH(obj); - data->data = (void *)shared; - Py_INCREF(obj); - data->obj = obj; // Will be "released" (decref'ed) when data released. - data->new_object = _new_str_object; - data->free = PyMem_Free; - return 0; -} - -static PyObject * -_new_long_object(_PyCrossInterpreterData *data) -{ - return PyLong_FromSsize_t((Py_ssize_t)(data->data)); -} - -static int -_long_shared(PyObject *obj, _PyCrossInterpreterData *data) -{ - /* Note that this means the size of shareable ints is bounded by - * sys.maxsize. Hence on 32-bit architectures that is half the - * size of maximum shareable ints on 64-bit. - */ - Py_ssize_t value = PyLong_AsSsize_t(obj); - if (value == -1 && PyErr_Occurred()) { - if (PyErr_ExceptionMatches(PyExc_OverflowError)) { - PyErr_SetString(PyExc_OverflowError, "try sending as bytes"); - } - return -1; - } - data->data = (void *)value; - data->obj = NULL; - data->new_object = _new_long_object; - data->free = NULL; - return 0; -} - -static PyObject * -_new_none_object(_PyCrossInterpreterData *data) -{ - // XXX Singleton refcounts are problematic across interpreters... - Py_INCREF(Py_None); - return Py_None; -} - -static int -_none_shared(PyObject *obj, _PyCrossInterpreterData *data) -{ - data->data = NULL; - // data->obj remains NULL - data->new_object = _new_none_object; - data->free = NULL; // There is nothing to free. - return 0; -} - -static void -_register_builtins_for_crossinterpreter_data(struct _xidregistry *xidregistry) -{ - // None - if (_register_xidata(xidregistry, (PyTypeObject *)PyObject_Type(Py_None), _none_shared) != 0) { - Py_FatalError("could not register None for cross-interpreter sharing"); - } - - // int - if (_register_xidata(xidregistry, &PyLong_Type, _long_shared) != 0) { - Py_FatalError("could not register int for cross-interpreter sharing"); - } - - // bytes - if (_register_xidata(xidregistry, &PyBytes_Type, _bytes_shared) != 0) { - Py_FatalError("could not register bytes for cross-interpreter sharing"); - } - - // str - if (_register_xidata(xidregistry, &PyUnicode_Type, _str_shared) != 0) { - Py_FatalError("could not register str for cross-interpreter sharing"); - } -} - - -_PyFrameEvalFunction -_PyInterpreterState_GetEvalFrameFunc(PyInterpreterState *interp) -{ - return interp->eval_frame; -} - - -void -_PyInterpreterState_SetEvalFrameFunc(PyInterpreterState *interp, - _PyFrameEvalFunction eval_frame) -{ - interp->eval_frame = eval_frame; -} - - -const PyConfig* -_PyInterpreterState_GetConfig(PyInterpreterState *interp) -{ - return &interp->config; -} - - -int -_PyInterpreterState_GetConfigCopy(PyConfig *config) -{ - PyInterpreterState *interp = PyInterpreterState_Get(); - - PyStatus status = _PyConfig_Copy(config, &interp->config); - if (PyStatus_Exception(status)) { - _PyErr_SetFromPyStatus(status); - return -1; - } - return 0; -} - - -const PyConfig* -_Py_GetConfig(void) -{ - assert(PyGILState_Check()); - PyThreadState *tstate = _PyThreadState_GET(); - return _PyInterpreterState_GetConfig(tstate->interp); -} - -#ifdef __cplusplus -} -#endif diff --git a/contrib/tools/python3/src/Python/pystrcmp.c b/contrib/tools/python3/src/Python/pystrcmp.c deleted file mode 100644 index 9224ce4c706..00000000000 --- a/contrib/tools/python3/src/Python/pystrcmp.c +++ /dev/null @@ -1,30 +0,0 @@ -/* Cross platform case insensitive string compare functions - */ - -#include "Python.h" - -int -PyOS_mystrnicmp(const char *s1, const char *s2, Py_ssize_t size) -{ - const unsigned char *p1, *p2; - if (size == 0) - return 0; - p1 = (const unsigned char *)s1; - p2 = (const unsigned char *)s2; - for (; (--size > 0) && *p1 && *p2 && (tolower(*p1) == tolower(*p2)); - p1++, p2++) { - ; - } - return tolower(*p1) - tolower(*p2); -} - -int -PyOS_mystricmp(const char *s1, const char *s2) -{ - const unsigned char *p1 = (const unsigned char *)s1; - const unsigned char *p2 = (const unsigned char *)s2; - for (; *p1 && *p2 && (tolower(*p1) == tolower(*p2)); p1++, p2++) { - ; - } - return (tolower(*p1) - tolower(*p2)); -} diff --git a/contrib/tools/python3/src/Python/pystrhex.c b/contrib/tools/python3/src/Python/pystrhex.c deleted file mode 100644 index b74e57ad913..00000000000 --- a/contrib/tools/python3/src/Python/pystrhex.c +++ /dev/null @@ -1,172 +0,0 @@ -/* bytes to hex implementation */ - -#include "Python.h" - -#include "pystrhex.h" - -static PyObject *_Py_strhex_impl(const char* argbuf, const Py_ssize_t arglen, - const PyObject* sep, int bytes_per_sep_group, - const int return_bytes) -{ - assert(arglen >= 0); - - Py_UCS1 sep_char = 0; - if (sep) { - Py_ssize_t seplen = PyObject_Length((PyObject*)sep); - if (seplen < 0) { - return NULL; - } - if (seplen != 1) { - PyErr_SetString(PyExc_ValueError, "sep must be length 1."); - return NULL; - } - if (PyUnicode_Check(sep)) { - if (PyUnicode_READY(sep)) - return NULL; - if (PyUnicode_KIND(sep) != PyUnicode_1BYTE_KIND) { - PyErr_SetString(PyExc_ValueError, "sep must be ASCII."); - return NULL; - } - sep_char = PyUnicode_READ_CHAR(sep, 0); - } - else if (PyBytes_Check(sep)) { - sep_char = PyBytes_AS_STRING(sep)[0]; - } - else { - PyErr_SetString(PyExc_TypeError, "sep must be str or bytes."); - return NULL; - } - if (sep_char > 127 && !return_bytes) { - PyErr_SetString(PyExc_ValueError, "sep must be ASCII."); - return NULL; - } - } - else { - bytes_per_sep_group = 0; - } - - unsigned int abs_bytes_per_sep = abs(bytes_per_sep_group); - Py_ssize_t resultlen = 0; - if (bytes_per_sep_group && arglen > 0) { - /* How many sep characters we'll be inserting. */ - resultlen = (arglen - 1) / abs_bytes_per_sep; - } - /* Bounds checking for our Py_ssize_t indices. */ - if (arglen >= PY_SSIZE_T_MAX / 2 - resultlen) { - return PyErr_NoMemory(); - } - resultlen += arglen * 2; - - if ((size_t)abs_bytes_per_sep >= (size_t)arglen) { - bytes_per_sep_group = 0; - abs_bytes_per_sep = 0; - } - - PyObject *retval; - Py_UCS1 *retbuf; - if (return_bytes) { - /* If _PyBytes_FromSize() were public we could avoid malloc+copy. */ - retval = PyBytes_FromStringAndSize(NULL, resultlen); - if (!retval) { - return NULL; - } - retbuf = (Py_UCS1 *)PyBytes_AS_STRING(retval); - } - else { - retval = PyUnicode_New(resultlen, 127); - if (!retval) { - return NULL; - } - retbuf = PyUnicode_1BYTE_DATA(retval); - } - - /* Hexlify */ - Py_ssize_t i, j; - unsigned char c; - - if (bytes_per_sep_group == 0) { - for (i = j = 0; i < arglen; ++i) { - assert((j + 1) < resultlen); - c = argbuf[i]; - retbuf[j++] = Py_hexdigits[c >> 4]; - retbuf[j++] = Py_hexdigits[c & 0x0f]; - } - assert(j == resultlen); - } - else { - /* The number of complete chunk+sep periods */ - Py_ssize_t chunks = (arglen - 1) / abs_bytes_per_sep; - Py_ssize_t chunk; - unsigned int k; - - if (bytes_per_sep_group < 0) { - i = j = 0; - for (chunk = 0; chunk < chunks; chunk++) { - for (k = 0; k < abs_bytes_per_sep; k++) { - c = argbuf[i++]; - retbuf[j++] = Py_hexdigits[c >> 4]; - retbuf[j++] = Py_hexdigits[c & 0x0f]; - } - retbuf[j++] = sep_char; - } - while (i < arglen) { - c = argbuf[i++]; - retbuf[j++] = Py_hexdigits[c >> 4]; - retbuf[j++] = Py_hexdigits[c & 0x0f]; - } - assert(j == resultlen); - } - else { - i = arglen - 1; - j = resultlen - 1; - for (chunk = 0; chunk < chunks; chunk++) { - for (k = 0; k < abs_bytes_per_sep; k++) { - c = argbuf[i--]; - retbuf[j--] = Py_hexdigits[c & 0x0f]; - retbuf[j--] = Py_hexdigits[c >> 4]; - } - retbuf[j--] = sep_char; - } - while (i >= 0) { - c = argbuf[i--]; - retbuf[j--] = Py_hexdigits[c & 0x0f]; - retbuf[j--] = Py_hexdigits[c >> 4]; - } - assert(j == -1); - } - } - -#ifdef Py_DEBUG - if (!return_bytes) { - assert(_PyUnicode_CheckConsistency(retval, 1)); - } -#endif - - return retval; -} - -PyObject * _Py_strhex(const char* argbuf, const Py_ssize_t arglen) -{ - return _Py_strhex_impl(argbuf, arglen, NULL, 0, 0); -} - -/* Same as above but returns a bytes() instead of str() to avoid the - * need to decode the str() when bytes are needed. */ -PyObject * _Py_strhex_bytes(const char* argbuf, const Py_ssize_t arglen) -{ - return _Py_strhex_impl(argbuf, arglen, NULL, 0, 1); -} - -/* These variants include support for a separator between every N bytes: */ - -PyObject * _Py_strhex_with_sep(const char* argbuf, const Py_ssize_t arglen, const PyObject* sep, const int bytes_per_group) -{ - return _Py_strhex_impl(argbuf, arglen, sep, bytes_per_group, 0); -} - -/* Same as above but returns a bytes() instead of str() to avoid the - * need to decode the str() when bytes are needed. */ -PyObject * _Py_strhex_bytes_with_sep(const char* argbuf, const Py_ssize_t arglen, const PyObject* sep, const int bytes_per_group) -{ - return _Py_strhex_impl(argbuf, arglen, sep, bytes_per_group, 1); -} diff --git a/contrib/tools/python3/src/Python/pystrtod.c b/contrib/tools/python3/src/Python/pystrtod.c deleted file mode 100644 index 9145d4eba12..00000000000 --- a/contrib/tools/python3/src/Python/pystrtod.c +++ /dev/null @@ -1,1307 +0,0 @@ -/* -*- Mode: C; c-file-style: "python" -*- */ - -#include <Python.h> -#include "pycore_dtoa.h" -#include <locale.h> - -/* Case-insensitive string match used for nan and inf detection; t should be - lower-case. Returns 1 for a successful match, 0 otherwise. */ - -static int -case_insensitive_match(const char *s, const char *t) -{ - while(*t && Py_TOLOWER(*s) == *t) { - s++; - t++; - } - return *t ? 0 : 1; -} - -/* _Py_parse_inf_or_nan: Attempt to parse a string of the form "nan", "inf" or - "infinity", with an optional leading sign of "+" or "-". On success, - return the NaN or Infinity as a double and set *endptr to point just beyond - the successfully parsed portion of the string. On failure, return -1.0 and - set *endptr to point to the start of the string. */ - -#ifndef PY_NO_SHORT_FLOAT_REPR - -double -_Py_parse_inf_or_nan(const char *p, char **endptr) -{ - double retval; - const char *s; - int negate = 0; - - s = p; - if (*s == '-') { - negate = 1; - s++; - } - else if (*s == '+') { - s++; - } - if (case_insensitive_match(s, "inf")) { - s += 3; - if (case_insensitive_match(s, "inity")) - s += 5; - retval = _Py_dg_infinity(negate); - } - else if (case_insensitive_match(s, "nan")) { - s += 3; - retval = _Py_dg_stdnan(negate); - } - else { - s = p; - retval = -1.0; - } - *endptr = (char *)s; - return retval; -} - -#else - -double -_Py_parse_inf_or_nan(const char *p, char **endptr) -{ - double retval; - const char *s; - int negate = 0; - - s = p; - if (*s == '-') { - negate = 1; - s++; - } - else if (*s == '+') { - s++; - } - if (case_insensitive_match(s, "inf")) { - s += 3; - if (case_insensitive_match(s, "inity")) - s += 5; - retval = negate ? -Py_HUGE_VAL : Py_HUGE_VAL; - } -#ifdef Py_NAN - else if (case_insensitive_match(s, "nan")) { - s += 3; - retval = negate ? -Py_NAN : Py_NAN; - } -#endif - else { - s = p; - retval = -1.0; - } - *endptr = (char *)s; - return retval; -} - -#endif - -/** - * _PyOS_ascii_strtod: - * @nptr: the string to convert to a numeric value. - * @endptr: if non-%NULL, it returns the character after - * the last character used in the conversion. - * - * Converts a string to a #gdouble value. - * This function behaves like the standard strtod() function - * does in the C locale. It does this without actually - * changing the current locale, since that would not be - * thread-safe. - * - * This function is typically used when reading configuration - * files or other non-user input that should be locale independent. - * To handle input from the user you should normally use the - * locale-sensitive system strtod() function. - * - * If the correct value would cause overflow, plus or minus %HUGE_VAL - * is returned (according to the sign of the value), and %ERANGE is - * stored in %errno. If the correct value would cause underflow, - * zero is returned and %ERANGE is stored in %errno. - * If memory allocation fails, %ENOMEM is stored in %errno. - * - * This function resets %errno before calling strtod() so that - * you can reliably detect overflow and underflow. - * - * Return value: the #gdouble value. - **/ - -#ifndef PY_NO_SHORT_FLOAT_REPR - -static double -_PyOS_ascii_strtod(const char *nptr, char **endptr) -{ - double result; - _Py_SET_53BIT_PRECISION_HEADER; - - assert(nptr != NULL); - /* Set errno to zero, so that we can distinguish zero results - and underflows */ - errno = 0; - - _Py_SET_53BIT_PRECISION_START; - result = _Py_dg_strtod(nptr, endptr); - _Py_SET_53BIT_PRECISION_END; - - if (*endptr == nptr) - /* string might represent an inf or nan */ - result = _Py_parse_inf_or_nan(nptr, endptr); - - return result; - -} - -#else - -/* - Use system strtod; since strtod is locale aware, we may - have to first fix the decimal separator. - - Note that unlike _Py_dg_strtod, the system strtod may not always give - correctly rounded results. -*/ - -static double -_PyOS_ascii_strtod(const char *nptr, char **endptr) -{ - char *fail_pos; - double val; - struct lconv *locale_data; - const char *decimal_point; - size_t decimal_point_len; - const char *p, *decimal_point_pos; - const char *end = NULL; /* Silence gcc */ - const char *digits_pos = NULL; - int negate = 0; - - assert(nptr != NULL); - - fail_pos = NULL; - - locale_data = localeconv(); - decimal_point = locale_data->decimal_point; - decimal_point_len = strlen(decimal_point); - - assert(decimal_point_len != 0); - - decimal_point_pos = NULL; - - /* Parse infinities and nans */ - val = _Py_parse_inf_or_nan(nptr, endptr); - if (*endptr != nptr) - return val; - - /* Set errno to zero, so that we can distinguish zero results - and underflows */ - errno = 0; - - /* We process the optional sign manually, then pass the remainder to - the system strtod. This ensures that the result of an underflow - has the correct sign. (bug #1725) */ - p = nptr; - /* Process leading sign, if present */ - if (*p == '-') { - negate = 1; - p++; - } - else if (*p == '+') { - p++; - } - - /* Some platform strtods accept hex floats; Python shouldn't (at the - moment), so we check explicitly for strings starting with '0x'. */ - if (*p == '0' && (*(p+1) == 'x' || *(p+1) == 'X')) - goto invalid_string; - - /* Check that what's left begins with a digit or decimal point */ - if (!Py_ISDIGIT(*p) && *p != '.') - goto invalid_string; - - digits_pos = p; - if (decimal_point[0] != '.' || - decimal_point[1] != 0) - { - /* Look for a '.' in the input; if present, it'll need to be - swapped for the current locale's decimal point before we - call strtod. On the other hand, if we find the current - locale's decimal point then the input is invalid. */ - while (Py_ISDIGIT(*p)) - p++; - - if (*p == '.') - { - decimal_point_pos = p++; - - /* locate end of number */ - while (Py_ISDIGIT(*p)) - p++; - - if (*p == 'e' || *p == 'E') - p++; - if (*p == '+' || *p == '-') - p++; - while (Py_ISDIGIT(*p)) - p++; - end = p; - } - else if (strncmp(p, decimal_point, decimal_point_len) == 0) - /* Python bug #1417699 */ - goto invalid_string; - /* For the other cases, we need not convert the decimal - point */ - } - - if (decimal_point_pos) { - char *copy, *c; - /* Create a copy of the input, with the '.' converted to the - locale-specific decimal point */ - copy = (char *)PyMem_Malloc(end - digits_pos + - 1 + decimal_point_len); - if (copy == NULL) { - *endptr = (char *)nptr; - errno = ENOMEM; - return val; - } - - c = copy; - memcpy(c, digits_pos, decimal_point_pos - digits_pos); - c += decimal_point_pos - digits_pos; - memcpy(c, decimal_point, decimal_point_len); - c += decimal_point_len; - memcpy(c, decimal_point_pos + 1, - end - (decimal_point_pos + 1)); - c += end - (decimal_point_pos + 1); - *c = 0; - - val = strtod(copy, &fail_pos); - - if (fail_pos) - { - if (fail_pos > decimal_point_pos) - fail_pos = (char *)digits_pos + - (fail_pos - copy) - - (decimal_point_len - 1); - else - fail_pos = (char *)digits_pos + - (fail_pos - copy); - } - - PyMem_Free(copy); - - } - else { - val = strtod(digits_pos, &fail_pos); - } - - if (fail_pos == digits_pos) - goto invalid_string; - - if (negate && fail_pos != nptr) - val = -val; - *endptr = fail_pos; - - return val; - - invalid_string: - *endptr = (char*)nptr; - errno = EINVAL; - return -1.0; -} - -#endif - -/* PyOS_string_to_double converts a null-terminated byte string s (interpreted - as a string of ASCII characters) to a float. The string should not have - leading or trailing whitespace. The conversion is independent of the - current locale. - - If endptr is NULL, try to convert the whole string. Raise ValueError and - return -1.0 if the string is not a valid representation of a floating-point - number. - - If endptr is non-NULL, try to convert as much of the string as possible. - If no initial segment of the string is the valid representation of a - floating-point number then *endptr is set to point to the beginning of the - string, -1.0 is returned and again ValueError is raised. - - On overflow (e.g., when trying to convert '1e500' on an IEEE 754 machine), - if overflow_exception is NULL then +-Py_HUGE_VAL is returned, and no Python - exception is raised. Otherwise, overflow_exception should point to - a Python exception, this exception will be raised, -1.0 will be returned, - and *endptr will point just past the end of the converted value. - - If any other failure occurs (for example lack of memory), -1.0 is returned - and the appropriate Python exception will have been set. -*/ - -double -PyOS_string_to_double(const char *s, - char **endptr, - PyObject *overflow_exception) -{ - double x, result=-1.0; - char *fail_pos; - - errno = 0; - x = _PyOS_ascii_strtod(s, &fail_pos); - - if (errno == ENOMEM) { - PyErr_NoMemory(); - fail_pos = (char *)s; - } - else if (!endptr && (fail_pos == s || *fail_pos != '\0')) - PyErr_Format(PyExc_ValueError, - "could not convert string to float: " - "'%.200s'", s); - else if (fail_pos == s) - PyErr_Format(PyExc_ValueError, - "could not convert string to float: " - "'%.200s'", s); - else if (errno == ERANGE && fabs(x) >= 1.0 && overflow_exception) - PyErr_Format(overflow_exception, - "value too large to convert to float: " - "'%.200s'", s); - else - result = x; - - if (endptr != NULL) - *endptr = fail_pos; - return result; -} - -/* Remove underscores that follow the underscore placement rule from - the string and then call the `innerfunc` function on the result. - It should return a new object or NULL on exception. - - `what` is used for the error message emitted when underscores are detected - that don't follow the rule. `arg` is an opaque pointer passed to the inner - function. - - This is used to implement underscore-agnostic conversion for floats - and complex numbers. -*/ -PyObject * -_Py_string_to_number_with_underscores( - const char *s, Py_ssize_t orig_len, const char *what, PyObject *obj, void *arg, - PyObject *(*innerfunc)(const char *, Py_ssize_t, void *)) -{ - char prev; - const char *p, *last; - char *dup, *end; - PyObject *result; - - assert(s[orig_len] == '\0'); - - if (strchr(s, '_') == NULL) { - return innerfunc(s, orig_len, arg); - } - - dup = PyMem_Malloc(orig_len + 1); - if (dup == NULL) { - return PyErr_NoMemory(); - } - end = dup; - prev = '\0'; - last = s + orig_len; - for (p = s; *p; p++) { - if (*p == '_') { - /* Underscores are only allowed after digits. */ - if (!(prev >= '0' && prev <= '9')) { - goto error; - } - } - else { - *end++ = *p; - /* Underscores are only allowed before digits. */ - if (prev == '_' && !(*p >= '0' && *p <= '9')) { - goto error; - } - } - prev = *p; - } - /* Underscores are not allowed at the end. */ - if (prev == '_') { - goto error; - } - /* No embedded NULs allowed. */ - if (p != last) { - goto error; - } - *end = '\0'; - result = innerfunc(dup, end - dup, arg); - PyMem_Free(dup); - return result; - - error: - PyMem_Free(dup); - PyErr_Format(PyExc_ValueError, - "could not convert string to %s: " - "%R", what, obj); - return NULL; -} - -#ifdef PY_NO_SHORT_FLOAT_REPR - -/* Given a string that may have a decimal point in the current - locale, change it back to a dot. Since the string cannot get - longer, no need for a maximum buffer size parameter. */ -Py_LOCAL_INLINE(void) -change_decimal_from_locale_to_dot(char* buffer) -{ - struct lconv *locale_data = localeconv(); - const char *decimal_point = locale_data->decimal_point; - - if (decimal_point[0] != '.' || decimal_point[1] != 0) { - size_t decimal_point_len = strlen(decimal_point); - - if (*buffer == '+' || *buffer == '-') - buffer++; - while (Py_ISDIGIT(*buffer)) - buffer++; - if (strncmp(buffer, decimal_point, decimal_point_len) == 0) { - *buffer = '.'; - buffer++; - if (decimal_point_len > 1) { - /* buffer needs to get smaller */ - size_t rest_len = strlen(buffer + - (decimal_point_len - 1)); - memmove(buffer, - buffer + (decimal_point_len - 1), - rest_len); - buffer[rest_len] = 0; - } - } - } -} - - -/* From the C99 standard, section 7.19.6: -The exponent always contains at least two digits, and only as many more digits -as necessary to represent the exponent. -*/ -#define MIN_EXPONENT_DIGITS 2 - -/* Ensure that any exponent, if present, is at least MIN_EXPONENT_DIGITS - in length. */ -Py_LOCAL_INLINE(void) -ensure_minimum_exponent_length(char* buffer, size_t buf_size) -{ - char *p = strpbrk(buffer, "eE"); - if (p && (*(p + 1) == '-' || *(p + 1) == '+')) { - char *start = p + 2; - int exponent_digit_cnt = 0; - int leading_zero_cnt = 0; - int in_leading_zeros = 1; - int significant_digit_cnt; - - /* Skip over the exponent and the sign. */ - p += 2; - - /* Find the end of the exponent, keeping track of leading - zeros. */ - while (*p && Py_ISDIGIT(*p)) { - if (in_leading_zeros && *p == '0') - ++leading_zero_cnt; - if (*p != '0') - in_leading_zeros = 0; - ++p; - ++exponent_digit_cnt; - } - - significant_digit_cnt = exponent_digit_cnt - leading_zero_cnt; - if (exponent_digit_cnt == MIN_EXPONENT_DIGITS) { - /* If there are 2 exactly digits, we're done, - regardless of what they contain */ - } - else if (exponent_digit_cnt > MIN_EXPONENT_DIGITS) { - int extra_zeros_cnt; - - /* There are more than 2 digits in the exponent. See - if we can delete some of the leading zeros */ - if (significant_digit_cnt < MIN_EXPONENT_DIGITS) - significant_digit_cnt = MIN_EXPONENT_DIGITS; - extra_zeros_cnt = exponent_digit_cnt - - significant_digit_cnt; - - /* Delete extra_zeros_cnt worth of characters from the - front of the exponent */ - assert(extra_zeros_cnt >= 0); - - /* Add one to significant_digit_cnt to copy the - trailing 0 byte, thus setting the length */ - memmove(start, - start + extra_zeros_cnt, - significant_digit_cnt + 1); - } - else { - /* If there are fewer than 2 digits, add zeros - until there are 2, if there's enough room */ - int zeros = MIN_EXPONENT_DIGITS - exponent_digit_cnt; - if (start + zeros + exponent_digit_cnt + 1 - < buffer + buf_size) { - memmove(start + zeros, start, - exponent_digit_cnt + 1); - memset(start, '0', zeros); - } - } - } -} - -/* Remove trailing zeros after the decimal point from a numeric string; also - remove the decimal point if all digits following it are zero. The numeric - string must end in '\0', and should not have any leading or trailing - whitespace. Assumes that the decimal point is '.'. */ -Py_LOCAL_INLINE(void) -remove_trailing_zeros(char *buffer) -{ - char *old_fraction_end, *new_fraction_end, *end, *p; - - p = buffer; - if (*p == '-' || *p == '+') - /* Skip leading sign, if present */ - ++p; - while (Py_ISDIGIT(*p)) - ++p; - - /* if there's no decimal point there's nothing to do */ - if (*p++ != '.') - return; - - /* scan any digits after the point */ - while (Py_ISDIGIT(*p)) - ++p; - old_fraction_end = p; - - /* scan up to ending '\0' */ - while (*p != '\0') - p++; - /* +1 to make sure that we move the null byte as well */ - end = p+1; - - /* scan back from fraction_end, looking for removable zeros */ - p = old_fraction_end; - while (*(p-1) == '0') - --p; - /* and remove point if we've got that far */ - if (*(p-1) == '.') - --p; - new_fraction_end = p; - - memmove(new_fraction_end, old_fraction_end, end-old_fraction_end); -} - -/* Ensure that buffer has a decimal point in it. The decimal point will not - be in the current locale, it will always be '.'. Don't add a decimal point - if an exponent is present. Also, convert to exponential notation where - adding a '.0' would produce too many significant digits (see issue 5864). - - Returns a pointer to the fixed buffer, or NULL on failure. -*/ -Py_LOCAL_INLINE(char *) -ensure_decimal_point(char* buffer, size_t buf_size, int precision) -{ - int digit_count, insert_count = 0, convert_to_exp = 0; - const char *chars_to_insert; - char *digits_start; - - /* search for the first non-digit character */ - char *p = buffer; - if (*p == '-' || *p == '+') - /* Skip leading sign, if present. I think this could only - ever be '-', but it can't hurt to check for both. */ - ++p; - digits_start = p; - while (*p && Py_ISDIGIT(*p)) - ++p; - digit_count = Py_SAFE_DOWNCAST(p - digits_start, Py_ssize_t, int); - - if (*p == '.') { - if (Py_ISDIGIT(*(p+1))) { - /* Nothing to do, we already have a decimal - point and a digit after it */ - } - else { - /* We have a decimal point, but no following - digit. Insert a zero after the decimal. */ - /* can't ever get here via PyOS_double_to_string */ - assert(precision == -1); - ++p; - chars_to_insert = "0"; - insert_count = 1; - } - } - else if (!(*p == 'e' || *p == 'E')) { - /* Don't add ".0" if we have an exponent. */ - if (digit_count == precision) { - /* issue 5864: don't add a trailing .0 in the case - where the '%g'-formatted result already has as many - significant digits as were requested. Switch to - exponential notation instead. */ - convert_to_exp = 1; - /* no exponent, no point, and we shouldn't land here - for infs and nans, so we must be at the end of the - string. */ - assert(*p == '\0'); - } - else { - assert(precision == -1 || digit_count < precision); - chars_to_insert = ".0"; - insert_count = 2; - } - } - if (insert_count) { - size_t buf_len = strlen(buffer); - if (buf_len + insert_count + 1 >= buf_size) { - /* If there is not enough room in the buffer - for the additional text, just skip it. It's - not worth generating an error over. */ - } - else { - memmove(p + insert_count, p, - buffer + strlen(buffer) - p + 1); - memcpy(p, chars_to_insert, insert_count); - } - } - if (convert_to_exp) { - int written; - size_t buf_avail; - p = digits_start; - /* insert decimal point */ - assert(digit_count >= 1); - memmove(p+2, p+1, digit_count); /* safe, but overwrites nul */ - p[1] = '.'; - p += digit_count+1; - assert(p <= buf_size+buffer); - buf_avail = buf_size+buffer-p; - if (buf_avail == 0) - return NULL; - /* Add exponent. It's okay to use lower case 'e': we only - arrive here as a result of using the empty format code or - repr/str builtins and those never want an upper case 'E' */ - written = PyOS_snprintf(p, buf_avail, "e%+.02d", digit_count-1); - if (!(0 <= written && - written < Py_SAFE_DOWNCAST(buf_avail, size_t, int))) - /* output truncated, or something else bad happened */ - return NULL; - remove_trailing_zeros(buffer); - } - return buffer; -} - -/* see FORMATBUFLEN in unicodeobject.c */ -#define FLOAT_FORMATBUFLEN 120 - -/** - * _PyOS_ascii_formatd: - * @buffer: A buffer to place the resulting string in - * @buf_size: The length of the buffer. - * @format: The printf()-style format to use for the - * code to use for converting. - * @d: The #gdouble to convert - * @precision: The precision to use when formatting. - * - * Converts a #gdouble to a string, using the '.' as - * decimal point. To format the number you pass in - * a printf()-style format string. Allowed conversion - * specifiers are 'e', 'E', 'f', 'F', 'g', 'G', and 'Z'. - * - * 'Z' is the same as 'g', except it always has a decimal and - * at least one digit after the decimal. - * - * Return value: The pointer to the buffer with the converted string. - * On failure returns NULL but does not set any Python exception. - **/ -static char * -_PyOS_ascii_formatd(char *buffer, - size_t buf_size, - const char *format, - double d, - int precision) -{ - char format_char; - size_t format_len = strlen(format); - - /* Issue 2264: code 'Z' requires copying the format. 'Z' is 'g', but - also with at least one character past the decimal. */ - char tmp_format[FLOAT_FORMATBUFLEN]; - - /* The last character in the format string must be the format char */ - format_char = format[format_len - 1]; - - if (format[0] != '%') - return NULL; - - /* I'm not sure why this test is here. It's ensuring that the format - string after the first character doesn't have a single quote, a - lowercase l, or a percent. This is the reverse of the commented-out - test about 10 lines ago. */ - if (strpbrk(format + 1, "'l%")) - return NULL; - - /* Also curious about this function is that it accepts format strings - like "%xg", which are invalid for floats. In general, the - interface to this function is not very good, but changing it is - difficult because it's a public API. */ - - if (!(format_char == 'e' || format_char == 'E' || - format_char == 'f' || format_char == 'F' || - format_char == 'g' || format_char == 'G' || - format_char == 'Z')) - return NULL; - - /* Map 'Z' format_char to 'g', by copying the format string and - replacing the final char with a 'g' */ - if (format_char == 'Z') { - if (format_len + 1 >= sizeof(tmp_format)) { - /* The format won't fit in our copy. Error out. In - practice, this will never happen and will be - detected by returning NULL */ - return NULL; - } - strcpy(tmp_format, format); - tmp_format[format_len - 1] = 'g'; - format = tmp_format; - } - - - /* Have PyOS_snprintf do the hard work */ - PyOS_snprintf(buffer, buf_size, format, d); - - /* Do various fixups on the return string */ - - /* Get the current locale, and find the decimal point string. - Convert that string back to a dot. */ - change_decimal_from_locale_to_dot(buffer); - - /* If an exponent exists, ensure that the exponent is at least - MIN_EXPONENT_DIGITS digits, providing the buffer is large enough - for the extra zeros. Also, if there are more than - MIN_EXPONENT_DIGITS, remove as many zeros as possible until we get - back to MIN_EXPONENT_DIGITS */ - ensure_minimum_exponent_length(buffer, buf_size); - - /* If format_char is 'Z', make sure we have at least one character - after the decimal point (and make sure we have a decimal point); - also switch to exponential notation in some edge cases where the - extra character would produce more significant digits that we - really want. */ - if (format_char == 'Z') - buffer = ensure_decimal_point(buffer, buf_size, precision); - - return buffer; -} - -/* The fallback code to use if _Py_dg_dtoa is not available. */ - -char * PyOS_double_to_string(double val, - char format_code, - int precision, - int flags, - int *type) -{ - char format[32]; - Py_ssize_t bufsize; - char *buf; - int t, exp; - int upper = 0; - - /* Validate format_code, and map upper and lower case */ - switch (format_code) { - case 'e': /* exponent */ - case 'f': /* fixed */ - case 'g': /* general */ - break; - case 'E': - upper = 1; - format_code = 'e'; - break; - case 'F': - upper = 1; - format_code = 'f'; - break; - case 'G': - upper = 1; - format_code = 'g'; - break; - case 'r': /* repr format */ - /* Supplied precision is unused, must be 0. */ - if (precision != 0) { - PyErr_BadInternalCall(); - return NULL; - } - /* The repr() precision (17 significant decimal digits) is the - minimal number that is guaranteed to have enough precision - so that if the number is read back in the exact same binary - value is recreated. This is true for IEEE floating point - by design, and also happens to work for all other modern - hardware. */ - precision = 17; - format_code = 'g'; - break; - default: - PyErr_BadInternalCall(); - return NULL; - } - - /* Here's a quick-and-dirty calculation to figure out how big a buffer - we need. In general, for a finite float we need: - - 1 byte for each digit of the decimal significand, and - - 1 for a possible sign - 1 for a possible decimal point - 2 for a possible [eE][+-] - 1 for each digit of the exponent; if we allow 19 digits - total then we're safe up to exponents of 2**63. - 1 for the trailing nul byte - - This gives a total of 24 + the number of digits in the significand, - and the number of digits in the significand is: - - for 'g' format: at most precision, except possibly - when precision == 0, when it's 1. - for 'e' format: precision+1 - for 'f' format: precision digits after the point, at least 1 - before. To figure out how many digits appear before the point - we have to examine the size of the number. If fabs(val) < 1.0 - then there will be only one digit before the point. If - fabs(val) >= 1.0, then there are at most - - 1+floor(log10(ceiling(fabs(val)))) - - digits before the point (where the 'ceiling' allows for the - possibility that the rounding rounds the integer part of val - up). A safe upper bound for the above quantity is - 1+floor(exp/3), where exp is the unique integer such that 0.5 - <= fabs(val)/2**exp < 1.0. This exp can be obtained from - frexp. - - So we allow room for precision+1 digits for all formats, plus an - extra floor(exp/3) digits for 'f' format. - - */ - - if (Py_IS_NAN(val) || Py_IS_INFINITY(val)) - /* 3 for 'inf'/'nan', 1 for sign, 1 for '\0' */ - bufsize = 5; - else { - bufsize = 25 + precision; - if (format_code == 'f' && fabs(val) >= 1.0) { - frexp(val, &exp); - bufsize += exp/3; - } - } - - buf = PyMem_Malloc(bufsize); - if (buf == NULL) { - PyErr_NoMemory(); - return NULL; - } - - /* Handle nan and inf. */ - if (Py_IS_NAN(val)) { - strcpy(buf, "nan"); - t = Py_DTST_NAN; - } else if (Py_IS_INFINITY(val)) { - if (copysign(1., val) == 1.) - strcpy(buf, "inf"); - else - strcpy(buf, "-inf"); - t = Py_DTST_INFINITE; - } else { - t = Py_DTST_FINITE; - if (flags & Py_DTSF_ADD_DOT_0) - format_code = 'Z'; - - PyOS_snprintf(format, sizeof(format), "%%%s.%i%c", - (flags & Py_DTSF_ALT ? "#" : ""), precision, - format_code); - _PyOS_ascii_formatd(buf, bufsize, format, val, precision); - } - - /* Add sign when requested. It's convenient (esp. when formatting - complex numbers) to include a sign even for inf and nan. */ - if (flags & Py_DTSF_SIGN && buf[0] != '-') { - size_t len = strlen(buf); - /* the bufsize calculations above should ensure that we've got - space to add a sign */ - assert((size_t)bufsize >= len+2); - memmove(buf+1, buf, len+1); - buf[0] = '+'; - } - if (upper) { - /* Convert to upper case. */ - char *p1; - for (p1 = buf; *p1; p1++) - *p1 = Py_TOUPPER(*p1); - } - - if (type) - *type = t; - return buf; -} - -#else - -/* _Py_dg_dtoa is available. */ - -/* I'm using a lookup table here so that I don't have to invent a non-locale - specific way to convert to uppercase */ -#define OFS_INF 0 -#define OFS_NAN 1 -#define OFS_E 2 - -/* The lengths of these are known to the code below, so don't change them */ -static const char * const lc_float_strings[] = { - "inf", - "nan", - "e", -}; -static const char * const uc_float_strings[] = { - "INF", - "NAN", - "E", -}; - - -/* Convert a double d to a string, and return a PyMem_Malloc'd block of - memory contain the resulting string. - - Arguments: - d is the double to be converted - format_code is one of 'e', 'f', 'g', 'r'. 'e', 'f' and 'g' - correspond to '%e', '%f' and '%g'; 'r' corresponds to repr. - mode is one of '0', '2' or '3', and is completely determined by - format_code: 'e' and 'g' use mode 2; 'f' mode 3, 'r' mode 0. - precision is the desired precision - always_add_sign is nonzero if a '+' sign should be included for positive - numbers - add_dot_0_if_integer is nonzero if integers in non-exponential form - should have ".0" added. Only applies to format codes 'r' and 'g'. - use_alt_formatting is nonzero if alternative formatting should be - used. Only applies to format codes 'e', 'f' and 'g'. For code 'g', - at most one of use_alt_formatting and add_dot_0_if_integer should - be nonzero. - type, if non-NULL, will be set to one of these constants to identify - the type of the 'd' argument: - Py_DTST_FINITE - Py_DTST_INFINITE - Py_DTST_NAN - - Returns a PyMem_Malloc'd block of memory containing the resulting string, - or NULL on error. If NULL is returned, the Python error has been set. - */ - -static char * -format_float_short(double d, char format_code, - int mode, int precision, - int always_add_sign, int add_dot_0_if_integer, - int use_alt_formatting, const char * const *float_strings, - int *type) -{ - char *buf = NULL; - char *p = NULL; - Py_ssize_t bufsize = 0; - char *digits, *digits_end; - int decpt_as_int, sign, exp_len, exp = 0, use_exp = 0; - Py_ssize_t decpt, digits_len, vdigits_start, vdigits_end; - _Py_SET_53BIT_PRECISION_HEADER; - - /* _Py_dg_dtoa returns a digit string (no decimal point or exponent). - Must be matched by a call to _Py_dg_freedtoa. */ - _Py_SET_53BIT_PRECISION_START; - digits = _Py_dg_dtoa(d, mode, precision, &decpt_as_int, &sign, - &digits_end); - _Py_SET_53BIT_PRECISION_END; - - decpt = (Py_ssize_t)decpt_as_int; - if (digits == NULL) { - /* The only failure mode is no memory. */ - PyErr_NoMemory(); - goto exit; - } - assert(digits_end != NULL && digits_end >= digits); - digits_len = digits_end - digits; - - if (digits_len && !Py_ISDIGIT(digits[0])) { - /* Infinities and nans here; adapt Gay's output, - so convert Infinity to inf and NaN to nan, and - ignore sign of nan. Then return. */ - - /* ignore the actual sign of a nan */ - if (digits[0] == 'n' || digits[0] == 'N') - sign = 0; - - /* We only need 5 bytes to hold the result "+inf\0" . */ - bufsize = 5; /* Used later in an assert. */ - buf = (char *)PyMem_Malloc(bufsize); - if (buf == NULL) { - PyErr_NoMemory(); - goto exit; - } - p = buf; - - if (sign == 1) { - *p++ = '-'; - } - else if (always_add_sign) { - *p++ = '+'; - } - if (digits[0] == 'i' || digits[0] == 'I') { - strncpy(p, float_strings[OFS_INF], 3); - p += 3; - - if (type) - *type = Py_DTST_INFINITE; - } - else if (digits[0] == 'n' || digits[0] == 'N') { - strncpy(p, float_strings[OFS_NAN], 3); - p += 3; - - if (type) - *type = Py_DTST_NAN; - } - else { - /* shouldn't get here: Gay's code should always return - something starting with a digit, an 'I', or 'N' */ - Py_UNREACHABLE(); - } - goto exit; - } - - /* The result must be finite (not inf or nan). */ - if (type) - *type = Py_DTST_FINITE; - - - /* We got digits back, format them. We may need to pad 'digits' - either on the left or right (or both) with extra zeros, so in - general the resulting string has the form - - [<sign>]<zeros><digits><zeros>[<exponent>] - - where either of the <zeros> pieces could be empty, and there's a - decimal point that could appear either in <digits> or in the - leading or trailing <zeros>. - - Imagine an infinite 'virtual' string vdigits, consisting of the - string 'digits' (starting at index 0) padded on both the left and - right with infinite strings of zeros. We want to output a slice - - vdigits[vdigits_start : vdigits_end] - - of this virtual string. Thus if vdigits_start < 0 then we'll end - up producing some leading zeros; if vdigits_end > digits_len there - will be trailing zeros in the output. The next section of code - determines whether to use an exponent or not, figures out the - position 'decpt' of the decimal point, and computes 'vdigits_start' - and 'vdigits_end'. */ - vdigits_end = digits_len; - switch (format_code) { - case 'e': - use_exp = 1; - vdigits_end = precision; - break; - case 'f': - vdigits_end = decpt + precision; - break; - case 'g': - if (decpt <= -4 || decpt > - (add_dot_0_if_integer ? precision-1 : precision)) - use_exp = 1; - if (use_alt_formatting) - vdigits_end = precision; - break; - case 'r': - /* convert to exponential format at 1e16. We used to convert - at 1e17, but that gives odd-looking results for some values - when a 16-digit 'shortest' repr is padded with bogus zeros. - For example, repr(2e16+8) would give 20000000000000010.0; - the true value is 20000000000000008.0. */ - if (decpt <= -4 || decpt > 16) - use_exp = 1; - break; - default: - PyErr_BadInternalCall(); - goto exit; - } - - /* if using an exponent, reset decimal point position to 1 and adjust - exponent accordingly.*/ - if (use_exp) { - exp = (int)decpt - 1; - decpt = 1; - } - /* ensure vdigits_start < decpt <= vdigits_end, or vdigits_start < - decpt < vdigits_end if add_dot_0_if_integer and no exponent */ - vdigits_start = decpt <= 0 ? decpt-1 : 0; - if (!use_exp && add_dot_0_if_integer) - vdigits_end = vdigits_end > decpt ? vdigits_end : decpt + 1; - else - vdigits_end = vdigits_end > decpt ? vdigits_end : decpt; - - /* double check inequalities */ - assert(vdigits_start <= 0 && - 0 <= digits_len && - digits_len <= vdigits_end); - /* decimal point should be in (vdigits_start, vdigits_end] */ - assert(vdigits_start < decpt && decpt <= vdigits_end); - - /* Compute an upper bound how much memory we need. This might be a few - chars too long, but no big deal. */ - bufsize = - /* sign, decimal point and trailing 0 byte */ - 3 + - - /* total digit count (including zero padding on both sides) */ - (vdigits_end - vdigits_start) + - - /* exponent "e+100", max 3 numerical digits */ - (use_exp ? 5 : 0); - - /* Now allocate the memory and initialize p to point to the start of - it. */ - buf = (char *)PyMem_Malloc(bufsize); - if (buf == NULL) { - PyErr_NoMemory(); - goto exit; - } - p = buf; - - /* Add a negative sign if negative, and a plus sign if non-negative - and always_add_sign is true. */ - if (sign == 1) - *p++ = '-'; - else if (always_add_sign) - *p++ = '+'; - - /* note that exactly one of the three 'if' conditions is true, - so we include exactly one decimal point */ - /* Zero padding on left of digit string */ - if (decpt <= 0) { - memset(p, '0', decpt-vdigits_start); - p += decpt - vdigits_start; - *p++ = '.'; - memset(p, '0', 0-decpt); - p += 0-decpt; - } - else { - memset(p, '0', 0-vdigits_start); - p += 0 - vdigits_start; - } - - /* Digits, with included decimal point */ - if (0 < decpt && decpt <= digits_len) { - strncpy(p, digits, decpt-0); - p += decpt-0; - *p++ = '.'; - strncpy(p, digits+decpt, digits_len-decpt); - p += digits_len-decpt; - } - else { - strncpy(p, digits, digits_len); - p += digits_len; - } - - /* And zeros on the right */ - if (digits_len < decpt) { - memset(p, '0', decpt-digits_len); - p += decpt-digits_len; - *p++ = '.'; - memset(p, '0', vdigits_end-decpt); - p += vdigits_end-decpt; - } - else { - memset(p, '0', vdigits_end-digits_len); - p += vdigits_end-digits_len; - } - - /* Delete a trailing decimal pt unless using alternative formatting. */ - if (p[-1] == '.' && !use_alt_formatting) - p--; - - /* Now that we've done zero padding, add an exponent if needed. */ - if (use_exp) { - *p++ = float_strings[OFS_E][0]; - exp_len = sprintf(p, "%+.02d", exp); - p += exp_len; - } - exit: - if (buf) { - *p = '\0'; - /* It's too late if this fails, as we've already stepped on - memory that isn't ours. But it's an okay debugging test. */ - assert(p-buf < bufsize); - } - if (digits) - _Py_dg_freedtoa(digits); - - return buf; -} - - -char * PyOS_double_to_string(double val, - char format_code, - int precision, - int flags, - int *type) -{ - const char * const *float_strings = lc_float_strings; - int mode; - - /* Validate format_code, and map upper and lower case. Compute the - mode and make any adjustments as needed. */ - switch (format_code) { - /* exponent */ - case 'E': - float_strings = uc_float_strings; - format_code = 'e'; - /* Fall through. */ - case 'e': - mode = 2; - precision++; - break; - - /* fixed */ - case 'F': - float_strings = uc_float_strings; - format_code = 'f'; - /* Fall through. */ - case 'f': - mode = 3; - break; - - /* general */ - case 'G': - float_strings = uc_float_strings; - format_code = 'g'; - /* Fall through. */ - case 'g': - mode = 2; - /* precision 0 makes no sense for 'g' format; interpret as 1 */ - if (precision == 0) - precision = 1; - break; - - /* repr format */ - case 'r': - mode = 0; - /* Supplied precision is unused, must be 0. */ - if (precision != 0) { - PyErr_BadInternalCall(); - return NULL; - } - break; - - default: - PyErr_BadInternalCall(); - return NULL; - } - - return format_float_short(val, format_code, mode, precision, - flags & Py_DTSF_SIGN, - flags & Py_DTSF_ADD_DOT_0, - flags & Py_DTSF_ALT, - float_strings, type); -} -#endif /* ifdef PY_NO_SHORT_FLOAT_REPR */ diff --git a/contrib/tools/python3/src/Python/pythonrun.c b/contrib/tools/python3/src/Python/pythonrun.c deleted file mode 100644 index 0f1794acec7..00000000000 --- a/contrib/tools/python3/src/Python/pythonrun.c +++ /dev/null @@ -1,1589 +0,0 @@ - -/* Top level execution of Python code (including in __main__) */ - -/* To help control the interfaces between the startup, execution and - * shutdown code, the phases are split across separate modules (bootstrap, - * pythonrun, shutdown) - */ - -/* TODO: Cull includes following phase split */ - -#include "Python.h" - -#include "pycore_ast.h" // PyAST_mod2obj -#include "pycore_compile.h" // _PyAST_Compile() -#include "pycore_interp.h" // PyInterpreterState.importlib -#include "pycore_object.h" // _PyDebug_PrintTotalRefs(), - // _PyType_GetQualName() -#include "pycore_parser.h" // _PyParser_ASTFromString() -#include "pycore_pyerrors.h" // _PyErr_Fetch, _Py_Offer_Suggestions -#include "pycore_pylifecycle.h" // _Py_UnhandledKeyboardInterrupt -#include "pycore_pystate.h" // _PyInterpreterState_GET() -#include "pycore_sysmodule.h" // _PySys_Audit() - -#include "token.h" // INDENT -#include "errcode.h" // E_EOF -#include "code.h" // PyCodeObject -#include "marshal.h" // PyMarshal_ReadLongFromFile() - -#ifdef MS_WINDOWS -# include "malloc.h" // alloca() -#endif - -#ifdef MS_WINDOWS -# undef BYTE -# include "windows.h" -#endif - - -_Py_IDENTIFIER(builtins); -_Py_IDENTIFIER(excepthook); -_Py_IDENTIFIER(flush); -_Py_IDENTIFIER(last_traceback); -_Py_IDENTIFIER(last_type); -_Py_IDENTIFIER(last_value); -_Py_IDENTIFIER(ps1); -_Py_IDENTIFIER(ps2); -_Py_IDENTIFIER(stdin); -_Py_IDENTIFIER(stdout); -_Py_IDENTIFIER(stderr); -_Py_static_string(PyId_string, "<string>"); - -#ifdef __cplusplus -extern "C" { -#endif - -/* Forward */ -static void flush_io(void); -static PyObject *run_mod(mod_ty, PyObject *, PyObject *, PyObject *, - PyCompilerFlags *, PyArena *); -static PyObject *run_pyc_file(FILE *, PyObject *, PyObject *, - PyCompilerFlags *); -static int PyRun_InteractiveOneObjectEx(FILE *, PyObject *, PyCompilerFlags *); -static PyObject* pyrun_file(FILE *fp, PyObject *filename, int start, - PyObject *globals, PyObject *locals, int closeit, - PyCompilerFlags *flags); - - -int -_PyRun_AnyFileObject(FILE *fp, PyObject *filename, int closeit, - PyCompilerFlags *flags) -{ - int decref_filename = 0; - if (filename == NULL) { - filename = PyUnicode_FromString("???"); - if (filename == NULL) { - PyErr_Print(); - return -1; - } - decref_filename = 1; - } - - int res; - if (_Py_FdIsInteractive(fp, filename)) { - res = _PyRun_InteractiveLoopObject(fp, filename, flags); - if (closeit) { - fclose(fp); - } - } - else { - res = _PyRun_SimpleFileObject(fp, filename, closeit, flags); - } - - if (decref_filename) { - Py_DECREF(filename); - } - return res; -} - - -/* Parse input from a file and execute it */ -int -PyRun_AnyFileExFlags(FILE *fp, const char *filename, int closeit, - PyCompilerFlags *flags) -{ - PyObject *filename_obj; - if (filename != NULL) { - filename_obj = PyUnicode_DecodeFSDefault(filename); - if (filename_obj == NULL) { - PyErr_Print(); - return -1; - } - } - else { - filename_obj = NULL; - } - int res = _PyRun_AnyFileObject(fp, filename_obj, closeit, flags); - Py_XDECREF(filename_obj); - return res; -} - - -int -_PyRun_InteractiveLoopObject(FILE *fp, PyObject *filename, PyCompilerFlags *flags) -{ - PyCompilerFlags local_flags = _PyCompilerFlags_INIT; - if (flags == NULL) { - flags = &local_flags; - } - - PyObject *v = _PySys_GetObjectId(&PyId_ps1); - if (v == NULL) { - _PySys_SetObjectId(&PyId_ps1, v = PyUnicode_FromString(">>> ")); - Py_XDECREF(v); - } - v = _PySys_GetObjectId(&PyId_ps2); - if (v == NULL) { - _PySys_SetObjectId(&PyId_ps2, v = PyUnicode_FromString("... ")); - Py_XDECREF(v); - } - -#ifdef Py_REF_DEBUG - int show_ref_count = _Py_GetConfig()->show_ref_count; -#endif - int err = 0; - int ret; - int nomem_count = 0; - do { - ret = PyRun_InteractiveOneObjectEx(fp, filename, flags); - if (ret == -1 && PyErr_Occurred()) { - /* Prevent an endless loop after multiple consecutive MemoryErrors - * while still allowing an interactive command to fail with a - * MemoryError. */ - if (PyErr_ExceptionMatches(PyExc_MemoryError)) { - if (++nomem_count > 16) { - PyErr_Clear(); - err = -1; - break; - } - } else { - nomem_count = 0; - } - PyErr_Print(); - flush_io(); - } else { - nomem_count = 0; - } -#ifdef Py_REF_DEBUG - if (show_ref_count) { - _PyDebug_PrintTotalRefs(); - } -#endif - } while (ret != E_EOF); - return err; -} - - -int -PyRun_InteractiveLoopFlags(FILE *fp, const char *filename, PyCompilerFlags *flags) -{ - PyObject *filename_obj = PyUnicode_DecodeFSDefault(filename); - if (filename_obj == NULL) { - PyErr_Print(); - return -1; - } - - int err = _PyRun_InteractiveLoopObject(fp, filename_obj, flags); - Py_DECREF(filename_obj); - return err; - -} - - -/* A PyRun_InteractiveOneObject() auxiliary function that does not print the - * error on failure. */ -static int -PyRun_InteractiveOneObjectEx(FILE *fp, PyObject *filename, - PyCompilerFlags *flags) -{ - PyObject *m, *d, *v, *w, *oenc = NULL, *mod_name; - mod_ty mod; - PyArena *arena; - const char *ps1 = "", *ps2 = "", *enc = NULL; - int errcode = 0; - _Py_IDENTIFIER(encoding); - _Py_IDENTIFIER(__main__); - - mod_name = _PyUnicode_FromId(&PyId___main__); /* borrowed */ - if (mod_name == NULL) { - return -1; - } - - if (fp == stdin) { - /* Fetch encoding from sys.stdin if possible. */ - v = _PySys_GetObjectId(&PyId_stdin); - if (v && v != Py_None) { - oenc = _PyObject_GetAttrId(v, &PyId_encoding); - if (oenc) - enc = PyUnicode_AsUTF8(oenc); - if (!enc) - PyErr_Clear(); - } - } - v = _PySys_GetObjectId(&PyId_ps1); - if (v != NULL) { - v = PyObject_Str(v); - if (v == NULL) - PyErr_Clear(); - else if (PyUnicode_Check(v)) { - ps1 = PyUnicode_AsUTF8(v); - if (ps1 == NULL) { - PyErr_Clear(); - ps1 = ""; - } - } - } - w = _PySys_GetObjectId(&PyId_ps2); - if (w != NULL) { - w = PyObject_Str(w); - if (w == NULL) - PyErr_Clear(); - else if (PyUnicode_Check(w)) { - ps2 = PyUnicode_AsUTF8(w); - if (ps2 == NULL) { - PyErr_Clear(); - ps2 = ""; - } - } - } - arena = _PyArena_New(); - if (arena == NULL) { - Py_XDECREF(v); - Py_XDECREF(w); - Py_XDECREF(oenc); - return -1; - } - - mod = _PyParser_ASTFromFile(fp, filename, enc, Py_single_input, - ps1, ps2, flags, &errcode, arena); - - Py_XDECREF(v); - Py_XDECREF(w); - Py_XDECREF(oenc); - if (mod == NULL) { - _PyArena_Free(arena); - if (errcode == E_EOF) { - PyErr_Clear(); - return E_EOF; - } - return -1; - } - m = PyImport_AddModuleObject(mod_name); - if (m == NULL) { - _PyArena_Free(arena); - return -1; - } - d = PyModule_GetDict(m); - v = run_mod(mod, filename, d, d, flags, arena); - _PyArena_Free(arena); - if (v == NULL) { - return -1; - } - Py_DECREF(v); - flush_io(); - return 0; -} - -int -PyRun_InteractiveOneObject(FILE *fp, PyObject *filename, PyCompilerFlags *flags) -{ - int res; - - res = PyRun_InteractiveOneObjectEx(fp, filename, flags); - if (res == -1) { - PyErr_Print(); - flush_io(); - } - return res; -} - -int -PyRun_InteractiveOneFlags(FILE *fp, const char *filename_str, PyCompilerFlags *flags) -{ - PyObject *filename; - int res; - - filename = PyUnicode_DecodeFSDefault(filename_str); - if (filename == NULL) { - PyErr_Print(); - return -1; - } - res = PyRun_InteractiveOneObject(fp, filename, flags); - Py_DECREF(filename); - return res; -} - - -/* Check whether a file maybe a pyc file: Look at the extension, - the file type, and, if we may close it, at the first few bytes. */ - -static int -maybe_pyc_file(FILE *fp, PyObject *filename, int closeit) -{ - PyObject *ext = PyUnicode_FromString(".pyc"); - if (ext == NULL) { - return -1; - } - Py_ssize_t endswith = PyUnicode_Tailmatch(filename, ext, 0, PY_SSIZE_T_MAX, +1); - Py_DECREF(ext); - if (endswith) { - return 1; - } - - /* Only look into the file if we are allowed to close it, since - it then should also be seekable. */ - if (!closeit) { - return 0; - } - - /* Read only two bytes of the magic. If the file was opened in - text mode, the bytes 3 and 4 of the magic (\r\n) might not - be read as they are on disk. */ - unsigned int halfmagic = PyImport_GetMagicNumber() & 0xFFFF; - unsigned char buf[2]; - /* Mess: In case of -x, the stream is NOT at its start now, - and ungetc() was used to push back the first newline, - which makes the current stream position formally undefined, - and a x-platform nightmare. - Unfortunately, we have no direct way to know whether -x - was specified. So we use a terrible hack: if the current - stream position is not 0, we assume -x was specified, and - give up. Bug 132850 on SourceForge spells out the - hopelessness of trying anything else (fseek and ftell - don't work predictably x-platform for text-mode files). - */ - int ispyc = 0; - if (ftell(fp) == 0) { - if (fread(buf, 1, 2, fp) == 2 && - ((unsigned int)buf[1]<<8 | buf[0]) == halfmagic) - ispyc = 1; - rewind(fp); - } - return ispyc; -} - - -static int -set_main_loader(PyObject *d, PyObject *filename, const char *loader_name) -{ - PyInterpreterState *interp = _PyInterpreterState_GET(); - PyObject *bootstrap = PyObject_GetAttrString(interp->importlib, - "_bootstrap_external"); - if (bootstrap == NULL) { - return -1; - } - - PyObject *loader_type = PyObject_GetAttrString(bootstrap, loader_name); - Py_DECREF(bootstrap); - if (loader_type == NULL) { - return -1; - } - - PyObject *loader = PyObject_CallFunction(loader_type, - "sO", "__main__", filename); - Py_DECREF(loader_type); - if (loader == NULL) { - return -1; - } - - if (PyDict_SetItemString(d, "__loader__", loader) < 0) { - Py_DECREF(loader); - return -1; - } - Py_DECREF(loader); - return 0; -} - - -int -_PyRun_SimpleFileObject(FILE *fp, PyObject *filename, int closeit, - PyCompilerFlags *flags) -{ - PyObject *m, *d, *v; - int set_file_name = 0, ret = -1; - - m = PyImport_AddModule("__main__"); - if (m == NULL) - return -1; - Py_INCREF(m); - d = PyModule_GetDict(m); - if (_PyDict_GetItemStringWithError(d, "__file__") == NULL) { - if (PyErr_Occurred()) { - goto done; - } - if (PyDict_SetItemString(d, "__file__", filename) < 0) { - goto done; - } - if (PyDict_SetItemString(d, "__cached__", Py_None) < 0) { - goto done; - } - set_file_name = 1; - } - - int pyc = maybe_pyc_file(fp, filename, closeit); - if (pyc < 0) { - goto done; - } - - if (pyc) { - FILE *pyc_fp; - /* Try to run a pyc file. First, re-open in binary */ - if (closeit) { - fclose(fp); - } - - pyc_fp = _Py_fopen_obj(filename, "rb"); - if (pyc_fp == NULL) { - fprintf(stderr, "python: Can't reopen .pyc file\n"); - goto done; - } - - if (set_main_loader(d, filename, "SourcelessFileLoader") < 0) { - fprintf(stderr, "python: failed to set __main__.__loader__\n"); - ret = -1; - fclose(pyc_fp); - goto done; - } - v = run_pyc_file(pyc_fp, d, d, flags); - } else { - /* When running from stdin, leave __main__.__loader__ alone */ - if (PyUnicode_CompareWithASCIIString(filename, "<stdin>") != 0 && - set_main_loader(d, filename, "SourceFileLoader") < 0) { - fprintf(stderr, "python: failed to set __main__.__loader__\n"); - ret = -1; - goto done; - } - v = pyrun_file(fp, filename, Py_file_input, d, d, - closeit, flags); - } - flush_io(); - if (v == NULL) { - Py_CLEAR(m); - PyErr_Print(); - goto done; - } - Py_DECREF(v); - ret = 0; - done: - if (set_file_name) { - if (PyDict_DelItemString(d, "__file__")) { - PyErr_Clear(); - } - if (PyDict_DelItemString(d, "__cached__")) { - PyErr_Clear(); - } - } - Py_XDECREF(m); - return ret; -} - - -int -PyRun_SimpleFileExFlags(FILE *fp, const char *filename, int closeit, - PyCompilerFlags *flags) -{ - PyObject *filename_obj = PyUnicode_DecodeFSDefault(filename); - if (filename_obj == NULL) { - return -1; - } - int res = _PyRun_SimpleFileObject(fp, filename_obj, closeit, flags); - Py_DECREF(filename_obj); - return res; -} - - -int -PyRun_SimpleStringFlags(const char *command, PyCompilerFlags *flags) -{ - PyObject *m, *d, *v; - m = PyImport_AddModule("__main__"); - if (m == NULL) - return -1; - d = PyModule_GetDict(m); - v = PyRun_StringFlags(command, Py_file_input, d, d, flags); - if (v == NULL) { - PyErr_Print(); - return -1; - } - Py_DECREF(v); - return 0; -} - -static int -parse_syntax_error(PyObject *err, PyObject **message, PyObject **filename, - Py_ssize_t *lineno, Py_ssize_t *offset, - Py_ssize_t* end_lineno, Py_ssize_t* end_offset, - PyObject **text) -{ - Py_ssize_t hold; - PyObject *v; - _Py_IDENTIFIER(msg); - _Py_IDENTIFIER(filename); - _Py_IDENTIFIER(lineno); - _Py_IDENTIFIER(offset); - _Py_IDENTIFIER(end_lineno); - _Py_IDENTIFIER(end_offset); - _Py_IDENTIFIER(text); - - *message = NULL; - *filename = NULL; - - /* new style errors. `err' is an instance */ - *message = _PyObject_GetAttrId(err, &PyId_msg); - if (!*message) - goto finally; - - v = _PyObject_GetAttrId(err, &PyId_filename); - if (!v) - goto finally; - if (v == Py_None) { - Py_DECREF(v); - *filename = _PyUnicode_FromId(&PyId_string); - if (*filename == NULL) - goto finally; - Py_INCREF(*filename); - } - else { - *filename = v; - } - - v = _PyObject_GetAttrId(err, &PyId_lineno); - if (!v) - goto finally; - hold = PyLong_AsSsize_t(v); - Py_DECREF(v); - if (hold < 0 && PyErr_Occurred()) - goto finally; - *lineno = hold; - - v = _PyObject_GetAttrId(err, &PyId_offset); - if (!v) - goto finally; - if (v == Py_None) { - *offset = -1; - Py_DECREF(v); - } else { - hold = PyLong_AsSsize_t(v); - Py_DECREF(v); - if (hold < 0 && PyErr_Occurred()) - goto finally; - *offset = hold; - } - - if (Py_TYPE(err) == (PyTypeObject*)PyExc_SyntaxError) { - v = _PyObject_GetAttrId(err, &PyId_end_lineno); - if (!v) { - PyErr_Clear(); - *end_lineno = *lineno; - } - else if (v == Py_None) { - *end_lineno = *lineno; - Py_DECREF(v); - } else { - hold = PyLong_AsSsize_t(v); - Py_DECREF(v); - if (hold < 0 && PyErr_Occurred()) - goto finally; - *end_lineno = hold; - } - - v = _PyObject_GetAttrId(err, &PyId_end_offset); - if (!v) { - PyErr_Clear(); - *end_offset = -1; - } - else if (v == Py_None) { - *end_offset = -1; - Py_DECREF(v); - } else { - hold = PyLong_AsSsize_t(v); - Py_DECREF(v); - if (hold < 0 && PyErr_Occurred()) - goto finally; - *end_offset = hold; - } - } else { - // SyntaxError subclasses - *end_lineno = *lineno; - *end_offset = -1; - } - - v = _PyObject_GetAttrId(err, &PyId_text); - if (!v) - goto finally; - if (v == Py_None) { - Py_DECREF(v); - *text = NULL; - } - else { - *text = v; - } - return 1; - -finally: - Py_XDECREF(*message); - Py_XDECREF(*filename); - return 0; -} - -static void -print_error_text(PyObject *f, Py_ssize_t offset, Py_ssize_t end_offset, PyObject *text_obj) -{ - size_t caret_repetitions = (end_offset > 0 && end_offset > offset) ? end_offset - offset : 1; - /* Convert text to a char pointer; return if error */ - const char *text = PyUnicode_AsUTF8(text_obj); - if (text == NULL) - return; - - /* Convert offset from 1-based to 0-based */ - offset--; - - /* Strip leading whitespace from text, adjusting offset as we go */ - while (*text == ' ' || *text == '\t' || *text == '\f') { - text++; - offset--; - } - - /* Calculate text length excluding trailing newline */ - Py_ssize_t len = strlen(text); - if (len > 0 && text[len-1] == '\n') { - len--; - } - - /* Clip offset to at most len */ - if (offset > len) { - offset = len; - } - - /* Skip past newlines embedded in text */ - for (;;) { - const char *nl = strchr(text, '\n'); - if (nl == NULL) { - break; - } - Py_ssize_t inl = nl - text; - if (inl >= offset) { - break; - } - inl += 1; - text += inl; - len -= inl; - offset -= (int)inl; - } - - /* Print text */ - PyFile_WriteString(" ", f); - PyFile_WriteString(text, f); - - /* Make sure there's a newline at the end */ - if (text[len] != '\n') { - PyFile_WriteString("\n", f); - } - - /* Don't print caret if it points to the left of the text */ - if (offset < 0) - return; - - /* Write caret line */ - PyFile_WriteString(" ", f); - while (--offset >= 0) { - PyFile_WriteString(" ", f); - } - for (size_t caret_iter=0; caret_iter < caret_repetitions ; caret_iter++) { - PyFile_WriteString("^", f); - } - PyFile_WriteString("\n", f); -} - - -int -_Py_HandleSystemExit(int *exitcode_p) -{ - int inspect = _Py_GetConfig()->inspect; - if (inspect) { - /* Don't exit if -i flag was given. This flag is set to 0 - * when entering interactive mode for inspecting. */ - return 0; - } - - if (!PyErr_ExceptionMatches(PyExc_SystemExit)) { - return 0; - } - - PyObject *exception, *value, *tb; - PyErr_Fetch(&exception, &value, &tb); - - fflush(stdout); - - int exitcode = 0; - if (value == NULL || value == Py_None) { - goto done; - } - - if (PyExceptionInstance_Check(value)) { - /* The error code should be in the `code' attribute. */ - _Py_IDENTIFIER(code); - PyObject *code = _PyObject_GetAttrId(value, &PyId_code); - if (code) { - Py_DECREF(value); - value = code; - if (value == Py_None) - goto done; - } - /* If we failed to dig out the 'code' attribute, - just let the else clause below print the error. */ - } - - if (PyLong_Check(value)) { - exitcode = (int)PyLong_AsLong(value); - } - else { - PyObject *sys_stderr = _PySys_GetObjectId(&PyId_stderr); - /* We clear the exception here to avoid triggering the assertion - * in PyObject_Str that ensures it won't silently lose exception - * details. - */ - PyErr_Clear(); - if (sys_stderr != NULL && sys_stderr != Py_None) { - PyFile_WriteObject(value, sys_stderr, Py_PRINT_RAW); - } else { - PyObject_Print(value, stderr, Py_PRINT_RAW); - fflush(stderr); - } - PySys_WriteStderr("\n"); - exitcode = 1; - } - - done: - /* Restore and clear the exception info, in order to properly decref - * the exception, value, and traceback. If we just exit instead, - * these leak, which confuses PYTHONDUMPREFS output, and may prevent - * some finalizers from running. - */ - PyErr_Restore(exception, value, tb); - PyErr_Clear(); - *exitcode_p = exitcode; - return 1; -} - - -static void -handle_system_exit(void) -{ - int exitcode; - if (_Py_HandleSystemExit(&exitcode)) { - Py_Exit(exitcode); - } -} - - -static void -_PyErr_PrintEx(PyThreadState *tstate, int set_sys_last_vars) -{ - PyObject *exception, *v, *tb, *hook; - - handle_system_exit(); - - _PyErr_Fetch(tstate, &exception, &v, &tb); - if (exception == NULL) { - goto done; - } - - _PyErr_NormalizeException(tstate, &exception, &v, &tb); - if (tb == NULL) { - tb = Py_None; - Py_INCREF(tb); - } - PyException_SetTraceback(v, tb); - if (exception == NULL) { - goto done; - } - - /* Now we know v != NULL too */ - if (set_sys_last_vars) { - if (_PySys_SetObjectId(&PyId_last_type, exception) < 0) { - _PyErr_Clear(tstate); - } - if (_PySys_SetObjectId(&PyId_last_value, v) < 0) { - _PyErr_Clear(tstate); - } - if (_PySys_SetObjectId(&PyId_last_traceback, tb) < 0) { - _PyErr_Clear(tstate); - } - } - hook = _PySys_GetObjectId(&PyId_excepthook); - if (_PySys_Audit(tstate, "sys.excepthook", "OOOO", hook ? hook : Py_None, - exception, v, tb) < 0) { - if (PyErr_ExceptionMatches(PyExc_RuntimeError)) { - PyErr_Clear(); - goto done; - } - _PyErr_WriteUnraisableMsg("in audit hook", NULL); - } - if (hook) { - PyObject* stack[3]; - PyObject *result; - - stack[0] = exception; - stack[1] = v; - stack[2] = tb; - result = _PyObject_FastCall(hook, stack, 3); - if (result == NULL) { - handle_system_exit(); - - PyObject *exception2, *v2, *tb2; - _PyErr_Fetch(tstate, &exception2, &v2, &tb2); - _PyErr_NormalizeException(tstate, &exception2, &v2, &tb2); - /* It should not be possible for exception2 or v2 - to be NULL. However PyErr_Display() can't - tolerate NULLs, so just be safe. */ - if (exception2 == NULL) { - exception2 = Py_None; - Py_INCREF(exception2); - } - if (v2 == NULL) { - v2 = Py_None; - Py_INCREF(v2); - } - fflush(stdout); - PySys_WriteStderr("Error in sys.excepthook:\n"); - PyErr_Display(exception2, v2, tb2); - PySys_WriteStderr("\nOriginal exception was:\n"); - PyErr_Display(exception, v, tb); - Py_DECREF(exception2); - Py_DECREF(v2); - Py_XDECREF(tb2); - } - Py_XDECREF(result); - } - else { - PySys_WriteStderr("sys.excepthook is missing\n"); - PyErr_Display(exception, v, tb); - } - -done: - Py_XDECREF(exception); - Py_XDECREF(v); - Py_XDECREF(tb); -} - -void -_PyErr_Print(PyThreadState *tstate) -{ - _PyErr_PrintEx(tstate, 1); -} - -void -PyErr_PrintEx(int set_sys_last_vars) -{ - PyThreadState *tstate = _PyThreadState_GET(); - _PyErr_PrintEx(tstate, set_sys_last_vars); -} - -void -PyErr_Print(void) -{ - PyErr_PrintEx(1); -} - -static void -print_exception(PyObject *f, PyObject *value) -{ - int err = 0; - PyObject *type, *tb, *tmp; - _Py_IDENTIFIER(print_file_and_line); - - if (!PyExceptionInstance_Check(value)) { - err = PyFile_WriteString("TypeError: print_exception(): Exception expected for value, ", f); - err += PyFile_WriteString(Py_TYPE(value)->tp_name, f); - err += PyFile_WriteString(" found\n", f); - if (err) - PyErr_Clear(); - return; - } - - Py_INCREF(value); - fflush(stdout); - type = (PyObject *) Py_TYPE(value); - tb = PyException_GetTraceback(value); - if (tb && tb != Py_None) - err = PyTraceBack_Print(tb, f); - if (err == 0 && - (err = _PyObject_LookupAttrId(value, &PyId_print_file_and_line, &tmp)) > 0) - { - PyObject *message, *filename, *text; - Py_ssize_t lineno, offset, end_lineno, end_offset; - err = 0; - Py_DECREF(tmp); - if (!parse_syntax_error(value, &message, &filename, - &lineno, &offset, - &end_lineno, &end_offset, &text)) - PyErr_Clear(); - else { - PyObject *line; - - Py_DECREF(value); - value = message; - - line = PyUnicode_FromFormat(" File \"%S\", line %zd\n", - filename, lineno); - Py_DECREF(filename); - if (line != NULL) { - PyFile_WriteObject(line, f, Py_PRINT_RAW); - Py_DECREF(line); - } - - if (text != NULL) { - Py_ssize_t line_size; - const char* error_line = PyUnicode_AsUTF8AndSize(text, &line_size); - // If the location of the error spawn multiple lines, we want - // to just print the first one and highlight everything until - // the end of that one since we don't support multi-line error - // messages. - if (end_lineno > lineno) { - end_offset = (error_line != NULL) ? line_size : -1; - } - // Limit the amount of '^' that we can display to - // the size of the text in the source line. - if (error_line != NULL && end_offset > line_size + 1) { - end_offset = line_size + 1; - } - print_error_text(f, offset, end_offset, text); - Py_DECREF(text); - } - - /* Can't be bothered to check all those - PyFile_WriteString() calls */ - if (PyErr_Occurred()) - err = -1; - } - } - if (err) { - /* Don't do anything else */ - } - else { - PyObject* modulename; - - _Py_IDENTIFIER(__module__); - assert(PyExceptionClass_Check(type)); - - modulename = _PyObject_GetAttrId(type, &PyId___module__); - if (modulename == NULL || !PyUnicode_Check(modulename)) - { - Py_XDECREF(modulename); - PyErr_Clear(); - err = PyFile_WriteString("<unknown>.", f); - } - else { - if (!_PyUnicode_EqualToASCIIId(modulename, &PyId_builtins)) - { - err = PyFile_WriteObject(modulename, f, Py_PRINT_RAW); - err += PyFile_WriteString(".", f); - } - Py_DECREF(modulename); - } - if (err == 0) { - PyObject* qualname = _PyType_GetQualName((PyTypeObject *)type); - if (qualname == NULL || !PyUnicode_Check(qualname)) { - Py_XDECREF(qualname); - PyErr_Clear(); - err = PyFile_WriteString("<unknown>", f); - } - else { - err = PyFile_WriteObject(qualname, f, Py_PRINT_RAW); - Py_DECREF(qualname); - } - } - } - if (err == 0 && (value != Py_None)) { - PyObject *s = PyObject_Str(value); - /* only print colon if the str() of the - object is not the empty string - */ - if (s == NULL) { - PyErr_Clear(); - err = -1; - PyFile_WriteString(": <exception str() failed>", f); - } - else if (!PyUnicode_Check(s) || - PyUnicode_GetLength(s) != 0) - err = PyFile_WriteString(": ", f); - if (err == 0) - err = PyFile_WriteObject(s, f, Py_PRINT_RAW); - Py_XDECREF(s); - } - /* try to write a newline in any case */ - if (err < 0) { - PyErr_Clear(); - } - PyObject* suggestions = _Py_Offer_Suggestions(value); - if (suggestions) { - // Add a trailer ". Did you mean: (...)?" - err = PyFile_WriteString(". Did you mean: '", f); - if (err == 0) { - err = PyFile_WriteObject(suggestions, f, Py_PRINT_RAW); - err += PyFile_WriteString("'?", f); - } - Py_DECREF(suggestions); - } else if (PyErr_Occurred()) { - PyErr_Clear(); - } - err += PyFile_WriteString("\n", f); - Py_XDECREF(tb); - Py_DECREF(value); - /* If an error happened here, don't show it. - XXX This is wrong, but too many callers rely on this behavior. */ - if (err != 0) - PyErr_Clear(); -} - -static const char cause_message[] = - "\nThe above exception was the direct cause " - "of the following exception:\n\n"; - -static const char context_message[] = - "\nDuring handling of the above exception, " - "another exception occurred:\n\n"; - -static void -print_exception_recursive(PyObject *f, PyObject *value, PyObject *seen) -{ - int err = 0, res; - PyObject *cause, *context; - - if (seen != NULL) { - /* Exception chaining */ - PyObject *value_id = PyLong_FromVoidPtr(value); - if (value_id == NULL || PySet_Add(seen, value_id) == -1) - PyErr_Clear(); - else if (PyExceptionInstance_Check(value)) { - PyObject *check_id = NULL; - cause = PyException_GetCause(value); - context = PyException_GetContext(value); - if (cause) { - check_id = PyLong_FromVoidPtr(cause); - if (check_id == NULL) { - res = -1; - } else { - res = PySet_Contains(seen, check_id); - Py_DECREF(check_id); - } - if (res == -1) - PyErr_Clear(); - if (res == 0) { - print_exception_recursive( - f, cause, seen); - err |= PyFile_WriteString( - cause_message, f); - } - } - else if (context && - !((PyBaseExceptionObject *)value)->suppress_context) { - check_id = PyLong_FromVoidPtr(context); - if (check_id == NULL) { - res = -1; - } else { - res = PySet_Contains(seen, check_id); - Py_DECREF(check_id); - } - if (res == -1) - PyErr_Clear(); - if (res == 0) { - print_exception_recursive( - f, context, seen); - err |= PyFile_WriteString( - context_message, f); - } - } - Py_XDECREF(context); - Py_XDECREF(cause); - } - Py_XDECREF(value_id); - } - print_exception(f, value); - if (err != 0) - PyErr_Clear(); -} - -void -_PyErr_Display(PyObject *file, PyObject *exception, PyObject *value, PyObject *tb) -{ - assert(file != NULL && file != Py_None); - - PyObject *seen; - if (PyExceptionInstance_Check(value) - && tb != NULL && PyTraceBack_Check(tb)) { - /* Put the traceback on the exception, otherwise it won't get - displayed. See issue #18776. */ - PyObject *cur_tb = PyException_GetTraceback(value); - if (cur_tb == NULL) - PyException_SetTraceback(value, tb); - else - Py_DECREF(cur_tb); - } - - /* We choose to ignore seen being possibly NULL, and report - at least the main exception (it could be a MemoryError). - */ - seen = PySet_New(NULL); - if (seen == NULL) { - PyErr_Clear(); - } - print_exception_recursive(file, value, seen); - Py_XDECREF(seen); - - /* Call file.flush() */ - PyObject *res = _PyObject_CallMethodIdNoArgs(file, &PyId_flush); - if (!res) { - /* Silently ignore file.flush() error */ - PyErr_Clear(); - } - else { - Py_DECREF(res); - } -} - -void -PyErr_Display(PyObject *exception, PyObject *value, PyObject *tb) -{ - PyObject *file = _PySys_GetObjectId(&PyId_stderr); - if (file == NULL) { - _PyObject_Dump(value); - fprintf(stderr, "lost sys.stderr\n"); - return; - } - if (file == Py_None) { - return; - } - Py_INCREF(file); - _PyErr_Display(file, exception, value, tb); - Py_DECREF(file); -} - -PyObject * -PyRun_StringFlags(const char *str, int start, PyObject *globals, - PyObject *locals, PyCompilerFlags *flags) -{ - PyObject *ret = NULL; - mod_ty mod; - PyArena *arena; - PyObject *filename; - - filename = _PyUnicode_FromId(&PyId_string); /* borrowed */ - if (filename == NULL) - return NULL; - - arena = _PyArena_New(); - if (arena == NULL) - return NULL; - - mod = _PyParser_ASTFromString(str, filename, start, flags, arena); - - if (mod != NULL) - ret = run_mod(mod, filename, globals, locals, flags, arena); - _PyArena_Free(arena); - return ret; -} - - -static PyObject * -pyrun_file(FILE *fp, PyObject *filename, int start, PyObject *globals, - PyObject *locals, int closeit, PyCompilerFlags *flags) -{ - PyArena *arena = _PyArena_New(); - if (arena == NULL) { - return NULL; - } - - mod_ty mod; - mod = _PyParser_ASTFromFile(fp, filename, NULL, start, NULL, NULL, - flags, NULL, arena); - - if (closeit) { - fclose(fp); - } - - PyObject *ret; - if (mod != NULL) { - ret = run_mod(mod, filename, globals, locals, flags, arena); - } - else { - ret = NULL; - } - _PyArena_Free(arena); - - return ret; -} - - -PyObject * -PyRun_FileExFlags(FILE *fp, const char *filename, int start, PyObject *globals, - PyObject *locals, int closeit, PyCompilerFlags *flags) -{ - PyObject *filename_obj = PyUnicode_DecodeFSDefault(filename); - if (filename_obj == NULL) { - return NULL; - } - - PyObject *res = pyrun_file(fp, filename_obj, start, globals, - locals, closeit, flags); - Py_DECREF(filename_obj); - return res; - -} - - -static void -flush_io(void) -{ - PyObject *f, *r; - PyObject *type, *value, *traceback; - - /* Save the current exception */ - PyErr_Fetch(&type, &value, &traceback); - - f = _PySys_GetObjectId(&PyId_stderr); - if (f != NULL) { - r = _PyObject_CallMethodIdNoArgs(f, &PyId_flush); - if (r) - Py_DECREF(r); - else - PyErr_Clear(); - } - f = _PySys_GetObjectId(&PyId_stdout); - if (f != NULL) { - r = _PyObject_CallMethodIdNoArgs(f, &PyId_flush); - if (r) - Py_DECREF(r); - else - PyErr_Clear(); - } - - PyErr_Restore(type, value, traceback); -} - -static PyObject * -run_eval_code_obj(PyThreadState *tstate, PyCodeObject *co, PyObject *globals, PyObject *locals) -{ - PyObject *v; - /* - * We explicitly re-initialize _Py_UnhandledKeyboardInterrupt every eval - * _just in case_ someone is calling into an embedded Python where they - * don't care about an uncaught KeyboardInterrupt exception (why didn't they - * leave config.install_signal_handlers set to 0?!?) but then later call - * Py_Main() itself (which _checks_ this flag and dies with a signal after - * its interpreter exits). We don't want a previous embedded interpreter's - * uncaught exception to trigger an unexplained signal exit from a future - * Py_Main() based one. - */ - _Py_UnhandledKeyboardInterrupt = 0; - - /* Set globals['__builtins__'] if it doesn't exist */ - if (globals != NULL && _PyDict_GetItemStringWithError(globals, "__builtins__") == NULL) { - if (PyErr_Occurred() || - PyDict_SetItemString(globals, "__builtins__", - tstate->interp->builtins) < 0) - { - return NULL; - } - } - - v = PyEval_EvalCode((PyObject*)co, globals, locals); - if (!v && _PyErr_Occurred(tstate) == PyExc_KeyboardInterrupt) { - _Py_UnhandledKeyboardInterrupt = 1; - } - return v; -} - -static PyObject * -run_mod(mod_ty mod, PyObject *filename, PyObject *globals, PyObject *locals, - PyCompilerFlags *flags, PyArena *arena) -{ - PyThreadState *tstate = _PyThreadState_GET(); - PyCodeObject *co = _PyAST_Compile(mod, filename, flags, -1, arena); - if (co == NULL) - return NULL; - - if (_PySys_Audit(tstate, "exec", "O", co) < 0) { - Py_DECREF(co); - return NULL; - } - - PyObject *v = run_eval_code_obj(tstate, co, globals, locals); - Py_DECREF(co); - return v; -} - -static PyObject * -run_pyc_file(FILE *fp, PyObject *globals, PyObject *locals, - PyCompilerFlags *flags) -{ - PyThreadState *tstate = _PyThreadState_GET(); - PyCodeObject *co; - PyObject *v; - long magic; - long PyImport_GetMagicNumber(void); - - magic = PyMarshal_ReadLongFromFile(fp); - if (magic != PyImport_GetMagicNumber()) { - if (!PyErr_Occurred()) - PyErr_SetString(PyExc_RuntimeError, - "Bad magic number in .pyc file"); - goto error; - } - /* Skip the rest of the header. */ - (void) PyMarshal_ReadLongFromFile(fp); - (void) PyMarshal_ReadLongFromFile(fp); - (void) PyMarshal_ReadLongFromFile(fp); - if (PyErr_Occurred()) { - goto error; - } - v = PyMarshal_ReadLastObjectFromFile(fp); - if (v == NULL || !PyCode_Check(v)) { - Py_XDECREF(v); - PyErr_SetString(PyExc_RuntimeError, - "Bad code object in .pyc file"); - goto error; - } - fclose(fp); - co = (PyCodeObject *)v; - v = run_eval_code_obj(tstate, co, globals, locals); - if (v && flags) - flags->cf_flags |= (co->co_flags & PyCF_MASK); - Py_DECREF(co); - return v; -error: - fclose(fp); - return NULL; -} - -PyObject * -Py_CompileStringObject(const char *str, PyObject *filename, int start, - PyCompilerFlags *flags, int optimize) -{ - PyCodeObject *co; - mod_ty mod; - PyArena *arena = _PyArena_New(); - if (arena == NULL) - return NULL; - - mod = _PyParser_ASTFromString(str, filename, start, flags, arena); - if (mod == NULL) { - _PyArena_Free(arena); - return NULL; - } - if (flags && (flags->cf_flags & PyCF_ONLY_AST)) { - PyObject *result = PyAST_mod2obj(mod); - _PyArena_Free(arena); - return result; - } - co = _PyAST_Compile(mod, filename, flags, optimize, arena); - _PyArena_Free(arena); - return (PyObject *)co; -} - -PyObject * -Py_CompileStringExFlags(const char *str, const char *filename_str, int start, - PyCompilerFlags *flags, int optimize) -{ - PyObject *filename, *co; - filename = PyUnicode_DecodeFSDefault(filename_str); - if (filename == NULL) - return NULL; - co = Py_CompileStringObject(str, filename, start, flags, optimize); - Py_DECREF(filename); - return co; -} - -const char * -_Py_SourceAsString(PyObject *cmd, const char *funcname, const char *what, PyCompilerFlags *cf, PyObject **cmd_copy) -{ - const char *str; - Py_ssize_t size; - Py_buffer view; - - *cmd_copy = NULL; - if (PyUnicode_Check(cmd)) { - cf->cf_flags |= PyCF_IGNORE_COOKIE; - str = PyUnicode_AsUTF8AndSize(cmd, &size); - if (str == NULL) - return NULL; - } - else if (PyBytes_Check(cmd)) { - str = PyBytes_AS_STRING(cmd); - size = PyBytes_GET_SIZE(cmd); - } - else if (PyByteArray_Check(cmd)) { - str = PyByteArray_AS_STRING(cmd); - size = PyByteArray_GET_SIZE(cmd); - } - else if (PyObject_GetBuffer(cmd, &view, PyBUF_SIMPLE) == 0) { - /* Copy to NUL-terminated buffer. */ - *cmd_copy = PyBytes_FromStringAndSize( - (const char *)view.buf, view.len); - PyBuffer_Release(&view); - if (*cmd_copy == NULL) { - return NULL; - } - str = PyBytes_AS_STRING(*cmd_copy); - size = PyBytes_GET_SIZE(*cmd_copy); - } - else { - PyErr_Format(PyExc_TypeError, - "%s() arg 1 must be a %s object", - funcname, what); - return NULL; - } - - if (strlen(str) != (size_t)size) { - PyErr_SetString(PyExc_ValueError, - "source code string cannot contain null bytes"); - Py_CLEAR(*cmd_copy); - return NULL; - } - return str; -} - -#if defined(USE_STACKCHECK) -#if defined(WIN32) && defined(_MSC_VER) - -/* Stack checking for Microsoft C */ - -#include <malloc.h> -#include <excpt.h> - -/* - * Return non-zero when we run out of memory on the stack; zero otherwise. - */ -int -PyOS_CheckStack(void) -{ - __try { - /* alloca throws a stack overflow exception if there's - not enough space left on the stack */ - alloca(PYOS_STACK_MARGIN * sizeof(void*)); - return 0; - } __except (GetExceptionCode() == STATUS_STACK_OVERFLOW ? - EXCEPTION_EXECUTE_HANDLER : - EXCEPTION_CONTINUE_SEARCH) { - int errcode = _resetstkoflw(); - if (errcode == 0) - { - Py_FatalError("Could not reset the stack!"); - } - } - return 1; -} - -#endif /* WIN32 && _MSC_VER */ - -/* Alternate implementations can be added here... */ - -#endif /* USE_STACKCHECK */ - -/* Deprecated C API functions still provided for binary compatibility */ - -#undef PyRun_AnyFile -PyAPI_FUNC(int) -PyRun_AnyFile(FILE *fp, const char *name) -{ - return PyRun_AnyFileExFlags(fp, name, 0, NULL); -} - -#undef PyRun_AnyFileEx -PyAPI_FUNC(int) -PyRun_AnyFileEx(FILE *fp, const char *name, int closeit) -{ - return PyRun_AnyFileExFlags(fp, name, closeit, NULL); -} - -#undef PyRun_AnyFileFlags -PyAPI_FUNC(int) -PyRun_AnyFileFlags(FILE *fp, const char *name, PyCompilerFlags *flags) -{ - return PyRun_AnyFileExFlags(fp, name, 0, flags); -} - -#undef PyRun_File -PyAPI_FUNC(PyObject *) -PyRun_File(FILE *fp, const char *p, int s, PyObject *g, PyObject *l) -{ - return PyRun_FileExFlags(fp, p, s, g, l, 0, NULL); -} - -#undef PyRun_FileEx -PyAPI_FUNC(PyObject *) -PyRun_FileEx(FILE *fp, const char *p, int s, PyObject *g, PyObject *l, int c) -{ - return PyRun_FileExFlags(fp, p, s, g, l, c, NULL); -} - -#undef PyRun_FileFlags -PyAPI_FUNC(PyObject *) -PyRun_FileFlags(FILE *fp, const char *p, int s, PyObject *g, PyObject *l, - PyCompilerFlags *flags) -{ - return PyRun_FileExFlags(fp, p, s, g, l, 0, flags); -} - -#undef PyRun_SimpleFile -PyAPI_FUNC(int) -PyRun_SimpleFile(FILE *f, const char *p) -{ - return PyRun_SimpleFileExFlags(f, p, 0, NULL); -} - -#undef PyRun_SimpleFileEx -PyAPI_FUNC(int) -PyRun_SimpleFileEx(FILE *f, const char *p, int c) -{ - return PyRun_SimpleFileExFlags(f, p, c, NULL); -} - - -#undef PyRun_String -PyAPI_FUNC(PyObject *) -PyRun_String(const char *str, int s, PyObject *g, PyObject *l) -{ - return PyRun_StringFlags(str, s, g, l, NULL); -} - -#undef PyRun_SimpleString -PyAPI_FUNC(int) -PyRun_SimpleString(const char *s) -{ - return PyRun_SimpleStringFlags(s, NULL); -} - -#undef Py_CompileString -PyAPI_FUNC(PyObject *) -Py_CompileString(const char *str, const char *p, int s) -{ - return Py_CompileStringExFlags(str, p, s, NULL, -1); -} - -#undef Py_CompileStringFlags -PyAPI_FUNC(PyObject *) -Py_CompileStringFlags(const char *str, const char *p, int s, - PyCompilerFlags *flags) -{ - return Py_CompileStringExFlags(str, p, s, flags, -1); -} - -#undef PyRun_InteractiveOne -PyAPI_FUNC(int) -PyRun_InteractiveOne(FILE *f, const char *p) -{ - return PyRun_InteractiveOneFlags(f, p, NULL); -} - -#undef PyRun_InteractiveLoop -PyAPI_FUNC(int) -PyRun_InteractiveLoop(FILE *f, const char *p) -{ - return PyRun_InteractiveLoopFlags(f, p, NULL); -} - -#ifdef __cplusplus -} -#endif diff --git a/contrib/tools/python3/src/Python/pytime.c b/contrib/tools/python3/src/Python/pytime.c deleted file mode 100644 index 1ef99aee748..00000000000 --- a/contrib/tools/python3/src/Python/pytime.c +++ /dev/null @@ -1,1149 +0,0 @@ -#include "Python.h" -#ifdef MS_WINDOWS -#include <winsock2.h> /* struct timeval */ -#endif - -#if defined(__APPLE__) -#include <mach/mach_time.h> /* mach_absolute_time(), mach_timebase_info() */ - -#if defined(__APPLE__) && defined(__has_builtin) -# if __has_builtin(__builtin_available) -# define HAVE_CLOCK_GETTIME_RUNTIME __builtin_available(macOS 10.12, iOS 10.0, tvOS 10.0, watchOS 3.0, *) -# endif -#endif -#endif - -#define _PyTime_check_mul_overflow(a, b) \ - (assert(b > 0), \ - (_PyTime_t)(a) < _PyTime_MIN / (_PyTime_t)(b) \ - || _PyTime_MAX / (_PyTime_t)(b) < (_PyTime_t)(a)) - -/* To millisecond (10^-3) */ -#define SEC_TO_MS 1000 - -/* To microseconds (10^-6) */ -#define MS_TO_US 1000 -#define SEC_TO_US (SEC_TO_MS * MS_TO_US) - -/* To nanoseconds (10^-9) */ -#define US_TO_NS 1000 -#define MS_TO_NS (MS_TO_US * US_TO_NS) -#define SEC_TO_NS (SEC_TO_MS * MS_TO_NS) - -/* Conversion from nanoseconds */ -#define NS_TO_MS (1000 * 1000) -#define NS_TO_US (1000) - -static void -error_time_t_overflow(void) -{ - PyErr_SetString(PyExc_OverflowError, - "timestamp out of range for platform time_t"); -} - -static void -_PyTime_overflow(void) -{ - PyErr_SetString(PyExc_OverflowError, - "timestamp too large to convert to C _PyTime_t"); -} - - -_PyTime_t -_PyTime_MulDiv(_PyTime_t ticks, _PyTime_t mul, _PyTime_t div) -{ - _PyTime_t intpart, remaining; - /* Compute (ticks * mul / div) in two parts to prevent integer overflow: - compute integer part, and then the remaining part. - - (ticks * mul) / div == (ticks / div) * mul + (ticks % div) * mul / div - - The caller must ensure that "(div - 1) * mul" cannot overflow. */ - intpart = ticks / div; - ticks %= div; - remaining = ticks * mul; - remaining /= div; - return intpart * mul + remaining; -} - - -time_t -_PyLong_AsTime_t(PyObject *obj) -{ -#if SIZEOF_TIME_T == SIZEOF_LONG_LONG - long long val; - val = PyLong_AsLongLong(obj); -#else - long val; - Py_BUILD_ASSERT(sizeof(time_t) <= sizeof(long)); - val = PyLong_AsLong(obj); -#endif - if (val == -1 && PyErr_Occurred()) { - if (PyErr_ExceptionMatches(PyExc_OverflowError)) { - error_time_t_overflow(); - } - return -1; - } - return (time_t)val; -} - -PyObject * -_PyLong_FromTime_t(time_t t) -{ -#if SIZEOF_TIME_T == SIZEOF_LONG_LONG - return PyLong_FromLongLong((long long)t); -#else - Py_BUILD_ASSERT(sizeof(time_t) <= sizeof(long)); - return PyLong_FromLong((long)t); -#endif -} - -/* Round to nearest with ties going to nearest even integer - (_PyTime_ROUND_HALF_EVEN) */ -static double -_PyTime_RoundHalfEven(double x) -{ - double rounded = round(x); - if (fabs(x-rounded) == 0.5) { - /* halfway case: round to even */ - rounded = 2.0*round(x/2.0); - } - return rounded; -} - -static double -_PyTime_Round(double x, _PyTime_round_t round) -{ - /* volatile avoids optimization changing how numbers are rounded */ - volatile double d; - - d = x; - if (round == _PyTime_ROUND_HALF_EVEN) { - d = _PyTime_RoundHalfEven(d); - } - else if (round == _PyTime_ROUND_CEILING) { - d = ceil(d); - } - else if (round == _PyTime_ROUND_FLOOR) { - d = floor(d); - } - else { - assert(round == _PyTime_ROUND_UP); - d = (d >= 0.0) ? ceil(d) : floor(d); - } - return d; -} - -static int -_PyTime_DoubleToDenominator(double d, time_t *sec, long *numerator, - long idenominator, _PyTime_round_t round) -{ - double denominator = (double)idenominator; - double intpart; - /* volatile avoids optimization changing how numbers are rounded */ - volatile double floatpart; - - floatpart = modf(d, &intpart); - - floatpart *= denominator; - floatpart = _PyTime_Round(floatpart, round); - if (floatpart >= denominator) { - floatpart -= denominator; - intpart += 1.0; - } - else if (floatpart < 0) { - floatpart += denominator; - intpart -= 1.0; - } - assert(0.0 <= floatpart && floatpart < denominator); - - if (!_Py_InIntegralTypeRange(time_t, intpart)) { - error_time_t_overflow(); - return -1; - } - *sec = (time_t)intpart; - *numerator = (long)floatpart; - assert(0 <= *numerator && *numerator < idenominator); - return 0; -} - -static int -_PyTime_ObjectToDenominator(PyObject *obj, time_t *sec, long *numerator, - long denominator, _PyTime_round_t round) -{ - assert(denominator >= 1); - - if (PyFloat_Check(obj)) { - double d = PyFloat_AsDouble(obj); - if (Py_IS_NAN(d)) { - *numerator = 0; - PyErr_SetString(PyExc_ValueError, "Invalid value NaN (not a number)"); - return -1; - } - return _PyTime_DoubleToDenominator(d, sec, numerator, - denominator, round); - } - else { - *sec = _PyLong_AsTime_t(obj); - *numerator = 0; - if (*sec == (time_t)-1 && PyErr_Occurred()) { - return -1; - } - return 0; - } -} - -int -_PyTime_ObjectToTime_t(PyObject *obj, time_t *sec, _PyTime_round_t round) -{ - if (PyFloat_Check(obj)) { - double intpart; - /* volatile avoids optimization changing how numbers are rounded */ - volatile double d; - - d = PyFloat_AsDouble(obj); - if (Py_IS_NAN(d)) { - PyErr_SetString(PyExc_ValueError, "Invalid value NaN (not a number)"); - return -1; - } - - d = _PyTime_Round(d, round); - (void)modf(d, &intpart); - - if (!_Py_InIntegralTypeRange(time_t, intpart)) { - error_time_t_overflow(); - return -1; - } - *sec = (time_t)intpart; - return 0; - } - else { - *sec = _PyLong_AsTime_t(obj); - if (*sec == (time_t)-1 && PyErr_Occurred()) { - return -1; - } - return 0; - } -} - -int -_PyTime_ObjectToTimespec(PyObject *obj, time_t *sec, long *nsec, - _PyTime_round_t round) -{ - return _PyTime_ObjectToDenominator(obj, sec, nsec, SEC_TO_NS, round); -} - -int -_PyTime_ObjectToTimeval(PyObject *obj, time_t *sec, long *usec, - _PyTime_round_t round) -{ - return _PyTime_ObjectToDenominator(obj, sec, usec, SEC_TO_US, round); -} - -_PyTime_t -_PyTime_FromSeconds(int seconds) -{ - _PyTime_t t; - /* ensure that integer overflow cannot happen, int type should have 32 - bits, whereas _PyTime_t type has at least 64 bits (SEC_TO_MS takes 30 - bits). */ - Py_BUILD_ASSERT(INT_MAX <= _PyTime_MAX / SEC_TO_NS); - Py_BUILD_ASSERT(INT_MIN >= _PyTime_MIN / SEC_TO_NS); - - t = (_PyTime_t)seconds; - assert((t >= 0 && t <= _PyTime_MAX / SEC_TO_NS) - || (t < 0 && t >= _PyTime_MIN / SEC_TO_NS)); - t *= SEC_TO_NS; - return t; -} - -_PyTime_t -_PyTime_FromNanoseconds(_PyTime_t ns) -{ - /* _PyTime_t already uses nanosecond resolution, no conversion needed */ - return ns; -} - -int -_PyTime_FromNanosecondsObject(_PyTime_t *tp, PyObject *obj) -{ - long long nsec; - _PyTime_t t; - - if (!PyLong_Check(obj)) { - PyErr_Format(PyExc_TypeError, "expect int, got %s", - Py_TYPE(obj)->tp_name); - return -1; - } - - Py_BUILD_ASSERT(sizeof(long long) == sizeof(_PyTime_t)); - nsec = PyLong_AsLongLong(obj); - if (nsec == -1 && PyErr_Occurred()) { - if (PyErr_ExceptionMatches(PyExc_OverflowError)) { - _PyTime_overflow(); - } - return -1; - } - - /* _PyTime_t already uses nanosecond resolution, no conversion needed */ - t = (_PyTime_t)nsec; - *tp = t; - return 0; -} - -#ifdef HAVE_CLOCK_GETTIME -static int -pytime_fromtimespec(_PyTime_t *tp, struct timespec *ts, int raise) -{ - _PyTime_t t, nsec; - int res = 0; - - Py_BUILD_ASSERT(sizeof(ts->tv_sec) <= sizeof(_PyTime_t)); - t = (_PyTime_t)ts->tv_sec; - - if (_PyTime_check_mul_overflow(t, SEC_TO_NS)) { - if (raise) { - _PyTime_overflow(); - res = -1; - } - t = (t > 0) ? _PyTime_MAX : _PyTime_MIN; - } - else { - t = t * SEC_TO_NS; - } - - nsec = ts->tv_nsec; - /* The following test is written for positive only nsec */ - assert(nsec >= 0); - if (t > _PyTime_MAX - nsec) { - if (raise) { - _PyTime_overflow(); - res = -1; - } - t = _PyTime_MAX; - } - else { - t += nsec; - } - - *tp = t; - return res; -} - -int -_PyTime_FromTimespec(_PyTime_t *tp, struct timespec *ts) -{ - return pytime_fromtimespec(tp, ts, 1); -} -#endif - -#if !defined(MS_WINDOWS) -static int -pytime_fromtimeval(_PyTime_t *tp, struct timeval *tv, int raise) -{ - _PyTime_t t, usec; - int res = 0; - - Py_BUILD_ASSERT(sizeof(tv->tv_sec) <= sizeof(_PyTime_t)); - t = (_PyTime_t)tv->tv_sec; - - if (_PyTime_check_mul_overflow(t, SEC_TO_NS)) { - if (raise) { - _PyTime_overflow(); - res = -1; - } - t = (t > 0) ? _PyTime_MAX : _PyTime_MIN; - } - else { - t = t * SEC_TO_NS; - } - - usec = (_PyTime_t)tv->tv_usec * US_TO_NS; - /* The following test is written for positive only usec */ - assert(usec >= 0); - if (t > _PyTime_MAX - usec) { - if (raise) { - _PyTime_overflow(); - res = -1; - } - t = _PyTime_MAX; - } - else { - t += usec; - } - - *tp = t; - return res; -} - -int -_PyTime_FromTimeval(_PyTime_t *tp, struct timeval *tv) -{ - return pytime_fromtimeval(tp, tv, 1); -} -#endif - -static int -_PyTime_FromDouble(_PyTime_t *t, double value, _PyTime_round_t round, - long unit_to_ns) -{ - /* volatile avoids optimization changing how numbers are rounded */ - volatile double d; - - /* convert to a number of nanoseconds */ - d = value; - d *= (double)unit_to_ns; - d = _PyTime_Round(d, round); - - if (!_Py_InIntegralTypeRange(_PyTime_t, d)) { - _PyTime_overflow(); - return -1; - } - *t = (_PyTime_t)d; - return 0; -} - -static int -_PyTime_FromObject(_PyTime_t *t, PyObject *obj, _PyTime_round_t round, - long unit_to_ns) -{ - if (PyFloat_Check(obj)) { - double d; - d = PyFloat_AsDouble(obj); - if (Py_IS_NAN(d)) { - PyErr_SetString(PyExc_ValueError, "Invalid value NaN (not a number)"); - return -1; - } - return _PyTime_FromDouble(t, d, round, unit_to_ns); - } - else { - long long sec; - Py_BUILD_ASSERT(sizeof(long long) <= sizeof(_PyTime_t)); - - sec = PyLong_AsLongLong(obj); - if (sec == -1 && PyErr_Occurred()) { - if (PyErr_ExceptionMatches(PyExc_OverflowError)) { - _PyTime_overflow(); - } - return -1; - } - - if (_PyTime_check_mul_overflow(sec, unit_to_ns)) { - _PyTime_overflow(); - return -1; - } - *t = sec * unit_to_ns; - return 0; - } -} - -int -_PyTime_FromSecondsObject(_PyTime_t *t, PyObject *obj, _PyTime_round_t round) -{ - return _PyTime_FromObject(t, obj, round, SEC_TO_NS); -} - -int -_PyTime_FromMillisecondsObject(_PyTime_t *t, PyObject *obj, _PyTime_round_t round) -{ - return _PyTime_FromObject(t, obj, round, MS_TO_NS); -} - -double -_PyTime_AsSecondsDouble(_PyTime_t t) -{ - /* volatile avoids optimization changing how numbers are rounded */ - volatile double d; - - if (t % SEC_TO_NS == 0) { - _PyTime_t secs; - /* Divide using integers to avoid rounding issues on the integer part. - 1e-9 cannot be stored exactly in IEEE 64-bit. */ - secs = t / SEC_TO_NS; - d = (double)secs; - } - else { - d = (double)t; - d /= 1e9; - } - return d; -} - -PyObject * -_PyTime_AsNanosecondsObject(_PyTime_t t) -{ - Py_BUILD_ASSERT(sizeof(long long) >= sizeof(_PyTime_t)); - return PyLong_FromLongLong((long long)t); -} - -static _PyTime_t -_PyTime_Divide(const _PyTime_t t, const _PyTime_t k, - const _PyTime_round_t round) -{ - assert(k > 1); - if (round == _PyTime_ROUND_HALF_EVEN) { - _PyTime_t x, r, abs_r; - x = t / k; - r = t % k; - abs_r = Py_ABS(r); - if (abs_r > k / 2 || (abs_r == k / 2 && (Py_ABS(x) & 1))) { - if (t >= 0) { - x++; - } - else { - x--; - } - } - return x; - } - else if (round == _PyTime_ROUND_CEILING) { - if (t >= 0) { - return (t + k - 1) / k; - } - else { - return t / k; - } - } - else if (round == _PyTime_ROUND_FLOOR){ - if (t >= 0) { - return t / k; - } - else { - return (t - (k - 1)) / k; - } - } - else { - assert(round == _PyTime_ROUND_UP); - if (t >= 0) { - return (t + k - 1) / k; - } - else { - return (t - (k - 1)) / k; - } - } -} - -_PyTime_t -_PyTime_AsMilliseconds(_PyTime_t t, _PyTime_round_t round) -{ - return _PyTime_Divide(t, NS_TO_MS, round); -} - -_PyTime_t -_PyTime_AsMicroseconds(_PyTime_t t, _PyTime_round_t round) -{ - return _PyTime_Divide(t, NS_TO_US, round); -} - -static int -_PyTime_AsTimeval_impl(_PyTime_t t, _PyTime_t *p_secs, int *p_us, - _PyTime_round_t round) -{ - _PyTime_t secs, ns; - int usec; - int res = 0; - - secs = t / SEC_TO_NS; - ns = t % SEC_TO_NS; - - usec = (int)_PyTime_Divide(ns, US_TO_NS, round); - if (usec < 0) { - usec += SEC_TO_US; - if (secs != _PyTime_MIN) { - secs -= 1; - } - else { - res = -1; - } - } - else if (usec >= SEC_TO_US) { - usec -= SEC_TO_US; - if (secs != _PyTime_MAX) { - secs += 1; - } - else { - res = -1; - } - } - assert(0 <= usec && usec < SEC_TO_US); - - *p_secs = secs; - *p_us = usec; - - return res; -} - -static int -_PyTime_AsTimevalStruct_impl(_PyTime_t t, struct timeval *tv, - _PyTime_round_t round, int raise) -{ - _PyTime_t secs, secs2; - int us; - int res; - - res = _PyTime_AsTimeval_impl(t, &secs, &us, round); - -#ifdef MS_WINDOWS - tv->tv_sec = (long)secs; -#else - tv->tv_sec = secs; -#endif - tv->tv_usec = us; - - secs2 = (_PyTime_t)tv->tv_sec; - if (res < 0 || secs2 != secs) { - if (raise) { - error_time_t_overflow(); - } - return -1; - } - return 0; -} - -int -_PyTime_AsTimeval(_PyTime_t t, struct timeval *tv, _PyTime_round_t round) -{ - return _PyTime_AsTimevalStruct_impl(t, tv, round, 1); -} - -int -_PyTime_AsTimeval_noraise(_PyTime_t t, struct timeval *tv, _PyTime_round_t round) -{ - return _PyTime_AsTimevalStruct_impl(t, tv, round, 0); -} - -int -_PyTime_AsTimevalTime_t(_PyTime_t t, time_t *p_secs, int *us, - _PyTime_round_t round) -{ - _PyTime_t secs; - int res; - - res = _PyTime_AsTimeval_impl(t, &secs, us, round); - - *p_secs = secs; - - if (res < 0 || (_PyTime_t)*p_secs != secs) { - error_time_t_overflow(); - return -1; - } - return 0; -} - - -#if defined(HAVE_CLOCK_GETTIME) || defined(HAVE_KQUEUE) -int -_PyTime_AsTimespec(_PyTime_t t, struct timespec *ts) -{ - _PyTime_t secs, nsec; - - secs = t / SEC_TO_NS; - nsec = t % SEC_TO_NS; - if (nsec < 0) { - nsec += SEC_TO_NS; - secs -= 1; - } - ts->tv_sec = (time_t)secs; - assert(0 <= nsec && nsec < SEC_TO_NS); - ts->tv_nsec = nsec; - - if ((_PyTime_t)ts->tv_sec != secs) { - error_time_t_overflow(); - return -1; - } - return 0; -} -#endif - -static int -py_get_system_clock(_PyTime_t *tp, _Py_clock_info_t *info, int raise) -{ -#ifdef MS_WINDOWS - FILETIME system_time; - ULARGE_INTEGER large; - - assert(info == NULL || raise); - - GetSystemTimeAsFileTime(&system_time); - large.u.LowPart = system_time.dwLowDateTime; - large.u.HighPart = system_time.dwHighDateTime; - /* 11,644,473,600,000,000,000: number of nanoseconds between - the 1st january 1601 and the 1st january 1970 (369 years + 89 leap - days). */ - *tp = large.QuadPart * 100 - 11644473600000000000; - if (info) { - DWORD timeAdjustment, timeIncrement; - BOOL isTimeAdjustmentDisabled, ok; - - info->implementation = "GetSystemTimeAsFileTime()"; - info->monotonic = 0; - ok = GetSystemTimeAdjustment(&timeAdjustment, &timeIncrement, - &isTimeAdjustmentDisabled); - if (!ok) { - PyErr_SetFromWindowsErr(0); - return -1; - } - info->resolution = timeIncrement * 1e-7; - info->adjustable = 1; - } - -#else /* MS_WINDOWS */ - int err; -#if defined(HAVE_CLOCK_GETTIME) - struct timespec ts; -#endif - -#if !defined(HAVE_CLOCK_GETTIME) || defined(__APPLE__) - struct timeval tv; -#endif - - assert(info == NULL || raise); - -#ifdef HAVE_CLOCK_GETTIME - -#ifdef HAVE_CLOCK_GETTIME_RUNTIME - if (HAVE_CLOCK_GETTIME_RUNTIME) { -#endif - - err = clock_gettime(CLOCK_REALTIME, &ts); - if (err) { - if (raise) { - PyErr_SetFromErrno(PyExc_OSError); - } - return -1; - } - if (pytime_fromtimespec(tp, &ts, raise) < 0) { - return -1; - } - - if (info) { - struct timespec res; - info->implementation = "clock_gettime(CLOCK_REALTIME)"; - info->monotonic = 0; - info->adjustable = 1; - if (clock_getres(CLOCK_REALTIME, &res) == 0) { - info->resolution = res.tv_sec + res.tv_nsec * 1e-9; - } - else { - info->resolution = 1e-9; - } - } - -#ifdef HAVE_CLOCK_GETTIME_RUNTIME - } else { -#endif - -#endif - -#if !defined(HAVE_CLOCK_GETTIME) || defined(HAVE_CLOCK_GETTIME_RUNTIME) - - /* test gettimeofday() */ - err = gettimeofday(&tv, (struct timezone *)NULL); - if (err) { - if (raise) { - PyErr_SetFromErrno(PyExc_OSError); - } - return -1; - } - if (pytime_fromtimeval(tp, &tv, raise) < 0) { - return -1; - } - - if (info) { - info->implementation = "gettimeofday()"; - info->resolution = 1e-6; - info->monotonic = 0; - info->adjustable = 1; - } - -#if defined(HAVE_CLOCK_GETTIME_RUNTIME) && defined(HAVE_CLOCK_GETTIME) - } /* end of availibity block */ -#endif - -#endif /* !HAVE_CLOCK_GETTIME */ -#endif /* !MS_WINDOWS */ - return 0; -} - -_PyTime_t -_PyTime_GetSystemClock(void) -{ - _PyTime_t t; - if (py_get_system_clock(&t, NULL, 0) < 0) { - // If clock_gettime(CLOCK_REALTIME) or gettimeofday() fails: - // silently ignore the failure and return 0. - t = 0; - } - return t; -} - -int -_PyTime_GetSystemClockWithInfo(_PyTime_t *t, _Py_clock_info_t *info) -{ - return py_get_system_clock(t, info, 1); -} - -#if __APPLE__ -static int -py_mach_timebase_info(_PyTime_t *pnumer, _PyTime_t *pdenom, int raise) -{ - static mach_timebase_info_data_t timebase; - /* According to the Technical Q&A QA1398, mach_timebase_info() cannot - fail: https://developer.apple.com/library/mac/#qa/qa1398/ */ - (void)mach_timebase_info(&timebase); - - /* Sanity check: should never occur in practice */ - if (timebase.numer < 1 || timebase.denom < 1) { - if (raise) { - PyErr_SetString(PyExc_RuntimeError, - "invalid mach_timebase_info"); - } - return -1; - } - - /* Check that timebase.numer and timebase.denom can be casted to - _PyTime_t. In practice, timebase uses uint32_t, so casting cannot - overflow. At the end, only make sure that the type is uint32_t - (_PyTime_t is 64-bit long). */ - Py_BUILD_ASSERT(sizeof(timebase.numer) < sizeof(_PyTime_t)); - Py_BUILD_ASSERT(sizeof(timebase.denom) < sizeof(_PyTime_t)); - - /* Make sure that (ticks * timebase.numer) cannot overflow in - _PyTime_MulDiv(), with ticks < timebase.denom. - - Known time bases: - - * always (1, 1) on Intel - * (1000000000, 33333335) or (1000000000, 25000000) on PowerPC - - None of these time bases can overflow with 64-bit _PyTime_t, but - check for overflow, just in case. */ - if ((_PyTime_t)timebase.numer > _PyTime_MAX / (_PyTime_t)timebase.denom) { - if (raise) { - PyErr_SetString(PyExc_OverflowError, - "mach_timebase_info is too large"); - } - return -1; - } - - *pnumer = (_PyTime_t)timebase.numer; - *pdenom = (_PyTime_t)timebase.denom; - return 0; -} -#endif - - -static int -py_get_monotonic_clock(_PyTime_t *tp, _Py_clock_info_t *info, int raise) -{ -#if defined(MS_WINDOWS) - ULONGLONG ticks; - _PyTime_t t; - - assert(info == NULL || raise); - - ticks = GetTickCount64(); - Py_BUILD_ASSERT(sizeof(ticks) <= sizeof(_PyTime_t)); - t = (_PyTime_t)ticks; - - if (_PyTime_check_mul_overflow(t, MS_TO_NS)) { - if (raise) { - _PyTime_overflow(); - return -1; - } - // Truncate to _PyTime_MAX silently. - *tp = _PyTime_MAX; - } - else { - *tp = t * MS_TO_NS; - } - - if (info) { - DWORD timeAdjustment, timeIncrement; - BOOL isTimeAdjustmentDisabled, ok; - info->implementation = "GetTickCount64()"; - info->monotonic = 1; - ok = GetSystemTimeAdjustment(&timeAdjustment, &timeIncrement, - &isTimeAdjustmentDisabled); - if (!ok) { - PyErr_SetFromWindowsErr(0); - return -1; - } - info->resolution = timeIncrement * 1e-7; - info->adjustable = 0; - } - -#elif defined(__APPLE__) - static _PyTime_t timebase_numer = 0; - static _PyTime_t timebase_denom = 0; - if (timebase_denom == 0) { - if (py_mach_timebase_info(&timebase_numer, &timebase_denom, raise) < 0) { - return -1; - } - } - - if (info) { - info->implementation = "mach_absolute_time()"; - info->resolution = (double)timebase_numer / (double)timebase_denom * 1e-9; - info->monotonic = 1; - info->adjustable = 0; - } - - uint64_t ticks = mach_absolute_time(); - *tp = _PyTime_MulDiv((_PyTime_t)ticks, timebase_numer, timebase_denom); - -#elif defined(__hpux) - hrtime_t time; - - time = gethrtime(); - if (time == -1) { - if (raise) { - PyErr_SetFromErrno(PyExc_OSError); - } - return -1; - } - - *tp = time; - - if (info) { - info->implementation = "gethrtime()"; - info->resolution = 1e-9; - info->monotonic = 1; - info->adjustable = 0; - } - -#else - struct timespec ts; -#ifdef CLOCK_HIGHRES - const clockid_t clk_id = CLOCK_HIGHRES; - const char *implementation = "clock_gettime(CLOCK_HIGHRES)"; -#else - const clockid_t clk_id = CLOCK_MONOTONIC; - const char *implementation = "clock_gettime(CLOCK_MONOTONIC)"; -#endif - - assert(info == NULL || raise); - - if (clock_gettime(clk_id, &ts) != 0) { - if (raise) { - PyErr_SetFromErrno(PyExc_OSError); - return -1; - } - return -1; - } - - if (info) { - struct timespec res; - info->monotonic = 1; - info->implementation = implementation; - info->adjustable = 0; - if (clock_getres(clk_id, &res) != 0) { - PyErr_SetFromErrno(PyExc_OSError); - return -1; - } - info->resolution = res.tv_sec + res.tv_nsec * 1e-9; - } - if (pytime_fromtimespec(tp, &ts, raise) < 0) { - return -1; - } -#endif - return 0; -} - -_PyTime_t -_PyTime_GetMonotonicClock(void) -{ - _PyTime_t t; - if (py_get_monotonic_clock(&t, NULL, 0) < 0) { - // If mach_timebase_info(), clock_gettime() or gethrtime() fails: - // silently ignore the failure and return 0. - t = 0; - } - return t; -} - -int -_PyTime_GetMonotonicClockWithInfo(_PyTime_t *tp, _Py_clock_info_t *info) -{ - return py_get_monotonic_clock(tp, info, 1); -} - - -#ifdef MS_WINDOWS -static int -win_perf_counter_frequency(LONGLONG *pfrequency, int raise) -{ - LONGLONG frequency; - - LARGE_INTEGER freq; - if (!QueryPerformanceFrequency(&freq)) { - if (raise) { - PyErr_SetFromWindowsErr(0); - } - return -1; - } - frequency = freq.QuadPart; - - /* Sanity check: should never occur in practice */ - if (frequency < 1) { - if (raise) { - PyErr_SetString(PyExc_RuntimeError, - "invalid QueryPerformanceFrequency"); - } - return -1; - } - - /* Check that frequency can be casted to _PyTime_t. - - Make also sure that (ticks * SEC_TO_NS) cannot overflow in - _PyTime_MulDiv(), with ticks < frequency. - - Known QueryPerformanceFrequency() values: - - * 10,000,000 (10 MHz): 100 ns resolution - * 3,579,545 Hz (3.6 MHz): 279 ns resolution - - None of these frequencies can overflow with 64-bit _PyTime_t, but - check for overflow, just in case. */ - if (frequency > _PyTime_MAX - || frequency > (LONGLONG)_PyTime_MAX / (LONGLONG)SEC_TO_NS) - { - if (raise) { - PyErr_SetString(PyExc_OverflowError, - "QueryPerformanceFrequency is too large"); - } - return -1; - } - - *pfrequency = frequency; - return 0; -} - - -static int -py_get_win_perf_counter(_PyTime_t *tp, _Py_clock_info_t *info, int raise) -{ - static LONGLONG frequency = 0; - if (frequency == 0) { - if (win_perf_counter_frequency(&frequency, raise) < 0) { - return -1; - } - } - - if (info) { - info->implementation = "QueryPerformanceCounter()"; - info->resolution = 1.0 / (double)frequency; - info->monotonic = 1; - info->adjustable = 0; - } - - LARGE_INTEGER now; - QueryPerformanceCounter(&now); - LONGLONG ticksll = now.QuadPart; - - /* Make sure that casting LONGLONG to _PyTime_t cannot overflow, - both types are signed */ - _PyTime_t ticks; - Py_BUILD_ASSERT(sizeof(ticksll) <= sizeof(ticks)); - ticks = (_PyTime_t)ticksll; - - *tp = _PyTime_MulDiv(ticks, SEC_TO_NS, (_PyTime_t)frequency); - return 0; -} -#endif - - -int -_PyTime_GetPerfCounterWithInfo(_PyTime_t *t, _Py_clock_info_t *info) -{ -#ifdef MS_WINDOWS - return py_get_win_perf_counter(t, info, 1); -#else - return _PyTime_GetMonotonicClockWithInfo(t, info); -#endif -} - - -_PyTime_t -_PyTime_GetPerfCounter(void) -{ - _PyTime_t t; - int res; -#ifdef MS_WINDOWS - res = py_get_win_perf_counter(&t, NULL, 0); -#else - res = py_get_monotonic_clock(&t, NULL, 0); -#endif - if (res < 0) { - // If win_perf_counter_frequency() or py_get_monotonic_clock() fails: - // silently ignore the failure and return 0. - t = 0; - } - return t; -} - - -int -_PyTime_localtime(time_t t, struct tm *tm) -{ -#ifdef MS_WINDOWS - int error; - - error = localtime_s(tm, &t); - if (error != 0) { - errno = error; - PyErr_SetFromErrno(PyExc_OSError); - return -1; - } - return 0; -#else /* !MS_WINDOWS */ - -#if defined(_AIX) && (SIZEOF_TIME_T < 8) - /* bpo-34373: AIX does not return NULL if t is too small or too large */ - if (t < -2145916800 /* 1902-01-01 */ - || t > 2145916800 /* 2038-01-01 */) { - errno = EINVAL; - PyErr_SetString(PyExc_OverflowError, - "localtime argument out of range"); - return -1; - } -#endif - - errno = 0; - if (localtime_r(&t, tm) == NULL) { - if (errno == 0) { - errno = EINVAL; - } - PyErr_SetFromErrno(PyExc_OSError); - return -1; - } - return 0; -#endif /* MS_WINDOWS */ -} - -int -_PyTime_gmtime(time_t t, struct tm *tm) -{ -#ifdef MS_WINDOWS - int error; - - error = gmtime_s(tm, &t); - if (error != 0) { - errno = error; - PyErr_SetFromErrno(PyExc_OSError); - return -1; - } - return 0; -#else /* !MS_WINDOWS */ - if (gmtime_r(&t, tm) == NULL) { -#ifdef EINVAL - if (errno == 0) { - errno = EINVAL; - } -#endif - PyErr_SetFromErrno(PyExc_OSError); - return -1; - } - return 0; -#endif /* MS_WINDOWS */ -} diff --git a/contrib/tools/python3/src/Python/stdlib_module_names.h b/contrib/tools/python3/src/Python/stdlib_module_names.h deleted file mode 100644 index 50cf340e543..00000000000 --- a/contrib/tools/python3/src/Python/stdlib_module_names.h +++ /dev/null @@ -1,308 +0,0 @@ -// Auto-generated by Tools/scripts/generate_stdlib_module_names.py. -// List used to create sys.stdlib_module_names. - -static const char* _Py_stdlib_module_names[] = { -"__future__", -"_abc", -"_aix_support", -"_ast", -"_asyncio", -"_bisect", -"_blake2", -"_bootsubprocess", -"_bz2", -"_codecs", -"_codecs_cn", -"_codecs_hk", -"_codecs_iso2022", -"_codecs_jp", -"_codecs_kr", -"_codecs_tw", -"_collections", -"_collections_abc", -"_compat_pickle", -"_compression", -"_contextvars", -"_crypt", -"_csv", -"_ctypes", -"_curses", -"_curses_panel", -"_datetime", -"_dbm", -"_decimal", -"_elementtree", -"_frozen_importlib", -"_frozen_importlib_external", -"_functools", -"_gdbm", -"_hashlib", -"_heapq", -"_imp", -"_io", -"_json", -"_locale", -"_lsprof", -"_lzma", -"_markupbase", -"_md5", -"_msi", -"_multibytecodec", -"_multiprocessing", -"_opcode", -"_operator", -"_osx_support", -"_overlapped", -"_pickle", -"_posixshmem", -"_posixsubprocess", -"_py_abc", -"_pydecimal", -"_pyio", -"_queue", -"_random", -"_scproxy", -"_sha1", -"_sha256", -"_sha3", -"_sha512", -"_signal", -"_sitebuiltins", -"_socket", -"_sqlite3", -"_sre", -"_ssl", -"_stat", -"_statistics", -"_string", -"_strptime", -"_struct", -"_symtable", -"_thread", -"_threading_local", -"_tkinter", -"_tracemalloc", -"_uuid", -"_warnings", -"_weakref", -"_weakrefset", -"_winapi", -"_zoneinfo", -"abc", -"aifc", -"antigravity", -"argparse", -"array", -"ast", -"asynchat", -"asyncio", -"asyncore", -"atexit", -"audioop", -"base64", -"bdb", -"binascii", -"binhex", -"bisect", -"builtins", -"bz2", -"cProfile", -"calendar", -"cgi", -"cgitb", -"chunk", -"cmath", -"cmd", -"code", -"codecs", -"codeop", -"collections", -"colorsys", -"compileall", -"concurrent", -"configparser", -"contextlib", -"contextvars", -"copy", -"copyreg", -"crypt", -"csv", -"ctypes", -"curses", -"dataclasses", -"datetime", -"dbm", -"decimal", -"difflib", -"dis", -"distutils", -"doctest", -"email", -"encodings", -"ensurepip", -"enum", -"errno", -"faulthandler", -"fcntl", -"filecmp", -"fileinput", -"fnmatch", -"fractions", -"ftplib", -"functools", -"gc", -"genericpath", -"getopt", -"getpass", -"gettext", -"glob", -"graphlib", -"grp", -"gzip", -"hashlib", -"heapq", -"hmac", -"html", -"http", -"idlelib", -"imaplib", -"imghdr", -"imp", -"importlib", -"inspect", -"io", -"ipaddress", -"itertools", -"json", -"keyword", -"lib2to3", -"linecache", -"locale", -"logging", -"lzma", -"mailbox", -"mailcap", -"marshal", -"math", -"mimetypes", -"mmap", -"modulefinder", -"msilib", -"msvcrt", -"multiprocessing", -"netrc", -"nis", -"nntplib", -"nt", -"ntpath", -"nturl2path", -"numbers", -"opcode", -"operator", -"optparse", -"os", -"ossaudiodev", -"pathlib", -"pdb", -"pickle", -"pickletools", -"pipes", -"pkgutil", -"platform", -"plistlib", -"poplib", -"posix", -"posixpath", -"pprint", -"profile", -"pstats", -"pty", -"pwd", -"py_compile", -"pyclbr", -"pydoc", -"pydoc_data", -"pyexpat", -"queue", -"quopri", -"random", -"re", -"readline", -"reprlib", -"resource", -"rlcompleter", -"runpy", -"sched", -"secrets", -"select", -"selectors", -"shelve", -"shlex", -"shutil", -"signal", -"site", -"smtpd", -"smtplib", -"sndhdr", -"socket", -"socketserver", -"spwd", -"sqlite3", -"sre_compile", -"sre_constants", -"sre_parse", -"ssl", -"stat", -"statistics", -"string", -"stringprep", -"struct", -"subprocess", -"sunau", -"symtable", -"sys", -"sysconfig", -"syslog", -"tabnanny", -"tarfile", -"telnetlib", -"tempfile", -"termios", -"textwrap", -"this", -"threading", -"time", -"timeit", -"tkinter", -"token", -"tokenize", -"trace", -"traceback", -"tracemalloc", -"tty", -"turtle", -"turtledemo", -"types", -"typing", -"unicodedata", -"unittest", -"urllib", -"uu", -"uuid", -"venv", -"warnings", -"wave", -"weakref", -"webbrowser", -"winreg", -"winsound", -"wsgiref", -"xdrlib", -"xml", -"xmlrpc", -"zipapp", -"zipfile", -"zipimport", -"zlib", -"zoneinfo", -}; diff --git a/contrib/tools/python3/src/Python/structmember.c b/contrib/tools/python3/src/Python/structmember.c deleted file mode 100644 index c7e318811d8..00000000000 --- a/contrib/tools/python3/src/Python/structmember.c +++ /dev/null @@ -1,296 +0,0 @@ - -/* Map C struct members to Python object attributes */ - -#include "Python.h" -#include "structmember.h" // PyMemberDef - -PyObject * -PyMember_GetOne(const char *obj_addr, PyMemberDef *l) -{ - PyObject *v; - - const char* addr = obj_addr + l->offset; - switch (l->type) { - case T_BOOL: - v = PyBool_FromLong(*(char*)addr); - break; - case T_BYTE: - v = PyLong_FromLong(*(char*)addr); - break; - case T_UBYTE: - v = PyLong_FromUnsignedLong(*(unsigned char*)addr); - break; - case T_SHORT: - v = PyLong_FromLong(*(short*)addr); - break; - case T_USHORT: - v = PyLong_FromUnsignedLong(*(unsigned short*)addr); - break; - case T_INT: - v = PyLong_FromLong(*(int*)addr); - break; - case T_UINT: - v = PyLong_FromUnsignedLong(*(unsigned int*)addr); - break; - case T_LONG: - v = PyLong_FromLong(*(long*)addr); - break; - case T_ULONG: - v = PyLong_FromUnsignedLong(*(unsigned long*)addr); - break; - case T_PYSSIZET: - v = PyLong_FromSsize_t(*(Py_ssize_t*)addr); - break; - case T_FLOAT: - v = PyFloat_FromDouble((double)*(float*)addr); - break; - case T_DOUBLE: - v = PyFloat_FromDouble(*(double*)addr); - break; - case T_STRING: - if (*(char**)addr == NULL) { - Py_INCREF(Py_None); - v = Py_None; - } - else - v = PyUnicode_FromString(*(char**)addr); - break; - case T_STRING_INPLACE: - v = PyUnicode_FromString((char*)addr); - break; - case T_CHAR: - v = PyUnicode_FromStringAndSize((char*)addr, 1); - break; - case T_OBJECT: - v = *(PyObject **)addr; - if (v == NULL) - v = Py_None; - Py_INCREF(v); - break; - case T_OBJECT_EX: - v = *(PyObject **)addr; - if (v == NULL) { - PyObject *obj = (PyObject *)obj_addr; - PyTypeObject *tp = Py_TYPE(obj); - PyErr_Format(PyExc_AttributeError, - "'%.200s' object has no attribute '%s'", - tp->tp_name, l->name); - } - Py_XINCREF(v); - break; - case T_LONGLONG: - v = PyLong_FromLongLong(*(long long *)addr); - break; - case T_ULONGLONG: - v = PyLong_FromUnsignedLongLong(*(unsigned long long *)addr); - break; - case T_NONE: - v = Py_None; - Py_INCREF(v); - break; - default: - PyErr_SetString(PyExc_SystemError, "bad memberdescr type"); - v = NULL; - } - return v; -} - -#define WARN(msg) \ - do { \ - if (PyErr_WarnEx(PyExc_RuntimeWarning, msg, 1) < 0) \ - return -1; \ - } while (0) - -int -PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v) -{ - PyObject *oldv; - - addr += l->offset; - - if ((l->flags & READONLY)) - { - PyErr_SetString(PyExc_AttributeError, "readonly attribute"); - return -1; - } - if (v == NULL) { - if (l->type == T_OBJECT_EX) { - /* Check if the attribute is set. */ - if (*(PyObject **)addr == NULL) { - PyErr_SetString(PyExc_AttributeError, l->name); - return -1; - } - } - else if (l->type != T_OBJECT) { - PyErr_SetString(PyExc_TypeError, - "can't delete numeric/char attribute"); - return -1; - } - } - switch (l->type) { - case T_BOOL:{ - if (!PyBool_Check(v)) { - PyErr_SetString(PyExc_TypeError, - "attribute value type must be bool"); - return -1; - } - if (v == Py_True) - *(char*)addr = (char) 1; - else - *(char*)addr = (char) 0; - break; - } - case T_BYTE:{ - long long_val = PyLong_AsLong(v); - if ((long_val == -1) && PyErr_Occurred()) - return -1; - *(char*)addr = (char)long_val; - /* XXX: For compatibility, only warn about truncations - for now. */ - if ((long_val > CHAR_MAX) || (long_val < CHAR_MIN)) - WARN("Truncation of value to char"); - break; - } - case T_UBYTE:{ - long long_val = PyLong_AsLong(v); - if ((long_val == -1) && PyErr_Occurred()) - return -1; - *(unsigned char*)addr = (unsigned char)long_val; - if ((long_val > UCHAR_MAX) || (long_val < 0)) - WARN("Truncation of value to unsigned char"); - break; - } - case T_SHORT:{ - long long_val = PyLong_AsLong(v); - if ((long_val == -1) && PyErr_Occurred()) - return -1; - *(short*)addr = (short)long_val; - if ((long_val > SHRT_MAX) || (long_val < SHRT_MIN)) - WARN("Truncation of value to short"); - break; - } - case T_USHORT:{ - long long_val = PyLong_AsLong(v); - if ((long_val == -1) && PyErr_Occurred()) - return -1; - *(unsigned short*)addr = (unsigned short)long_val; - if ((long_val > USHRT_MAX) || (long_val < 0)) - WARN("Truncation of value to unsigned short"); - break; - } - case T_INT:{ - long long_val = PyLong_AsLong(v); - if ((long_val == -1) && PyErr_Occurred()) - return -1; - *(int *)addr = (int)long_val; - if ((long_val > INT_MAX) || (long_val < INT_MIN)) - WARN("Truncation of value to int"); - break; - } - case T_UINT:{ - unsigned long ulong_val = PyLong_AsUnsignedLong(v); - if ((ulong_val == (unsigned long)-1) && PyErr_Occurred()) { - /* XXX: For compatibility, accept negative int values - as well. */ - PyErr_Clear(); - ulong_val = PyLong_AsLong(v); - if ((ulong_val == (unsigned long)-1) && - PyErr_Occurred()) - return -1; - *(unsigned int *)addr = (unsigned int)ulong_val; - WARN("Writing negative value into unsigned field"); - } else - *(unsigned int *)addr = (unsigned int)ulong_val; - if (ulong_val > UINT_MAX) - WARN("Truncation of value to unsigned int"); - break; - } - case T_LONG:{ - *(long*)addr = PyLong_AsLong(v); - if ((*(long*)addr == -1) && PyErr_Occurred()) - return -1; - break; - } - case T_ULONG:{ - *(unsigned long*)addr = PyLong_AsUnsignedLong(v); - if ((*(unsigned long*)addr == (unsigned long)-1) - && PyErr_Occurred()) { - /* XXX: For compatibility, accept negative int values - as well. */ - PyErr_Clear(); - *(unsigned long*)addr = PyLong_AsLong(v); - if ((*(unsigned long*)addr == (unsigned long)-1) - && PyErr_Occurred()) - return -1; - WARN("Writing negative value into unsigned field"); - } - break; - } - case T_PYSSIZET:{ - *(Py_ssize_t*)addr = PyLong_AsSsize_t(v); - if ((*(Py_ssize_t*)addr == (Py_ssize_t)-1) - && PyErr_Occurred()) - return -1; - break; - } - case T_FLOAT:{ - double double_val = PyFloat_AsDouble(v); - if ((double_val == -1) && PyErr_Occurred()) - return -1; - *(float*)addr = (float)double_val; - break; - } - case T_DOUBLE: - *(double*)addr = PyFloat_AsDouble(v); - if ((*(double*)addr == -1) && PyErr_Occurred()) - return -1; - break; - case T_OBJECT: - case T_OBJECT_EX: - Py_XINCREF(v); - oldv = *(PyObject **)addr; - *(PyObject **)addr = v; - Py_XDECREF(oldv); - break; - case T_CHAR: { - const char *string; - Py_ssize_t len; - - string = PyUnicode_AsUTF8AndSize(v, &len); - if (string == NULL || len != 1) { - PyErr_BadArgument(); - return -1; - } - *(char*)addr = string[0]; - break; - } - case T_STRING: - case T_STRING_INPLACE: - PyErr_SetString(PyExc_TypeError, "readonly attribute"); - return -1; - case T_LONGLONG:{ - long long value; - *(long long*)addr = value = PyLong_AsLongLong(v); - if ((value == -1) && PyErr_Occurred()) - return -1; - break; - } - case T_ULONGLONG:{ - unsigned long long value; - /* ??? PyLong_AsLongLong accepts an int, but PyLong_AsUnsignedLongLong - doesn't ??? */ - if (PyLong_Check(v)) - *(unsigned long long*)addr = value = PyLong_AsUnsignedLongLong(v); - else - *(unsigned long long*)addr = value = PyLong_AsLong(v); - if ((value == (unsigned long long)-1) && PyErr_Occurred()) - return -1; - break; - } - default: - PyErr_Format(PyExc_SystemError, - "bad memberdescr type for %s", l->name); - return -1; - } - return 0; -} diff --git a/contrib/tools/python3/src/Python/suggestions.c b/contrib/tools/python3/src/Python/suggestions.c deleted file mode 100644 index 4e2f9055779..00000000000 --- a/contrib/tools/python3/src/Python/suggestions.c +++ /dev/null @@ -1,289 +0,0 @@ -#include "Python.h" -#include "frameobject.h" - -#include "pycore_pyerrors.h" - -#define MAX_CANDIDATE_ITEMS 750 -#define MAX_STRING_SIZE 40 - -#define MOVE_COST 2 -#define CASE_COST 1 - -#define LEAST_FIVE_BITS(n) ((n) & 31) - -static inline int -substitution_cost(char a, char b) -{ - if (LEAST_FIVE_BITS(a) != LEAST_FIVE_BITS(b)) { - // Not the same, not a case flip. - return MOVE_COST; - } - if (a == b) { - return 0; - } - if ('A' <= a && a <= 'Z') { - a += ('a' - 'A'); - } - if ('A' <= b && b <= 'Z') { - b += ('a' - 'A'); - } - if (a == b) { - return CASE_COST; - } - return MOVE_COST; -} - -/* Calculate the Levenshtein distance between string1 and string2 */ -static Py_ssize_t -levenshtein_distance(const char *a, size_t a_size, - const char *b, size_t b_size, - size_t max_cost) -{ - static size_t buffer[MAX_STRING_SIZE]; - - // Both strings are the same (by identity) - if (a == b) { - return 0; - } - - // Trim away common affixes. - while (a_size && b_size && a[0] == b[0]) { - a++; a_size--; - b++; b_size--; - } - while (a_size && b_size && a[a_size-1] == b[b_size-1]) { - a_size--; - b_size--; - } - if (a_size == 0 || b_size == 0) { - return (a_size + b_size) * MOVE_COST; - } - if (a_size > MAX_STRING_SIZE || b_size > MAX_STRING_SIZE) { - return max_cost + 1; - } - - // Prefer shorter buffer - if (b_size < a_size) { - const char *t = a; a = b; b = t; - size_t t_size = a_size; a_size = b_size; b_size = t_size; - } - - // quick fail when a match is impossible. - if ((b_size - a_size) * MOVE_COST > max_cost) { - return max_cost + 1; - } - - // Instead of producing the whole traditional len(a)-by-len(b) - // matrix, we can update just one row in place. - // Initialize the buffer row - for (size_t i = 0; i < a_size; i++) { - // cost from b[:0] to a[:i+1] - buffer[i] = (i + 1) * MOVE_COST; - } - - size_t result = 0; - for (size_t b_index = 0; b_index < b_size; b_index++) { - char code = b[b_index]; - // cost(b[:b_index], a[:0]) == b_index * MOVE_COST - size_t distance = result = b_index * MOVE_COST; - size_t minimum = SIZE_MAX; - for (size_t index = 0; index < a_size; index++) { - - // cost(b[:b_index+1], a[:index+1]) = min( - // // 1) substitute - // cost(b[:b_index], a[:index]) - // + substitution_cost(b[b_index], a[index]), - // // 2) delete from b - // cost(b[:b_index], a[:index+1]) + MOVE_COST, - // // 3) delete from a - // cost(b[:b_index+1], a[index]) + MOVE_COST - // ) - - // 1) Previous distance in this row is cost(b[:b_index], a[:index]) - size_t substitute = distance + substitution_cost(code, a[index]); - // 2) cost(b[:b_index], a[:index+1]) from previous row - distance = buffer[index]; - // 3) existing result is cost(b[:b_index+1], a[index]) - - size_t insert_delete = Py_MIN(result, distance) + MOVE_COST; - result = Py_MIN(insert_delete, substitute); - - // cost(b[:b_index+1], a[:index+1]) - buffer[index] = result; - if (result < minimum) { - minimum = result; - } - } - if (minimum > max_cost) { - // Everything in this row is too big, so bail early. - return max_cost + 1; - } - } - return result; -} - -static inline PyObject * -calculate_suggestions(PyObject *dir, - PyObject *name) -{ - assert(!PyErr_Occurred()); - assert(PyList_CheckExact(dir)); - - Py_ssize_t dir_size = PyList_GET_SIZE(dir); - if (dir_size >= MAX_CANDIDATE_ITEMS) { - return NULL; - } - - Py_ssize_t suggestion_distance = PY_SSIZE_T_MAX; - PyObject *suggestion = NULL; - Py_ssize_t name_size; - const char *name_str = PyUnicode_AsUTF8AndSize(name, &name_size); - if (name_str == NULL) { - return NULL; - } - - for (int i = 0; i < dir_size; ++i) { - PyObject *item = PyList_GET_ITEM(dir, i); - Py_ssize_t item_size; - const char *item_str = PyUnicode_AsUTF8AndSize(item, &item_size); - if (item_str == NULL) { - return NULL; - } - if (PyUnicode_CompareWithASCIIString(name, item_str) == 0) { - continue; - } - // No more than 1/3 of the involved characters should need changed. - Py_ssize_t max_distance = (name_size + item_size + 3) * MOVE_COST / 6; - // Don't take matches we've already beaten. - max_distance = Py_MIN(max_distance, suggestion_distance - 1); - Py_ssize_t current_distance = - levenshtein_distance(name_str, name_size, - item_str, item_size, max_distance); - if (current_distance > max_distance) { - continue; - } - if (!suggestion || current_distance < suggestion_distance) { - suggestion = item; - suggestion_distance = current_distance; - } - } - Py_XINCREF(suggestion); - return suggestion; -} - -static PyObject * -offer_suggestions_for_attribute_error(PyAttributeErrorObject *exc) -{ - PyObject *name = exc->name; // borrowed reference - PyObject *obj = exc->obj; // borrowed reference - - // Abort if we don't have an attribute name or we have an invalid one - if (name == NULL || obj == NULL || !PyUnicode_CheckExact(name)) { - return NULL; - } - - PyObject *dir = PyObject_Dir(obj); - if (dir == NULL) { - return NULL; - } - - PyObject *suggestions = calculate_suggestions(dir, name); - Py_DECREF(dir); - return suggestions; -} - - -static PyObject * -offer_suggestions_for_name_error(PyNameErrorObject *exc) -{ - PyObject *name = exc->name; // borrowed reference - PyTracebackObject *traceback = (PyTracebackObject *) exc->traceback; // borrowed reference - // Abort if we don't have a variable name or we have an invalid one - // or if we don't have a traceback to work with - if (name == NULL || !PyUnicode_CheckExact(name) || - traceback == NULL || !Py_IS_TYPE(traceback, &PyTraceBack_Type) - ) { - return NULL; - } - - // Move to the traceback of the exception - while (1) { - PyTracebackObject *next = traceback->tb_next; - if (next == NULL || !Py_IS_TYPE(next, &PyTraceBack_Type)) { - break; - } - else { - traceback = next; - } - } - - PyFrameObject *frame = traceback->tb_frame; - assert(frame != NULL); - PyCodeObject *code = frame->f_code; - assert(code != NULL && code->co_varnames != NULL); - PyObject *dir = PySequence_List(code->co_varnames); - if (dir == NULL) { - return NULL; - } - - PyObject *suggestions = calculate_suggestions(dir, name); - Py_DECREF(dir); - if (suggestions != NULL) { - return suggestions; - } - - dir = PySequence_List(frame->f_globals); - if (dir == NULL) { - return NULL; - } - suggestions = calculate_suggestions(dir, name); - Py_DECREF(dir); - if (suggestions != NULL) { - return suggestions; - } - - dir = PySequence_List(frame->f_builtins); - if (dir == NULL) { - return NULL; - } - suggestions = calculate_suggestions(dir, name); - Py_DECREF(dir); - - return suggestions; -} - -// Offer suggestions for a given exception. Returns a python string object containing the -// suggestions. This function returns NULL if no suggestion was found or if an exception happened, -// users must call PyErr_Occurred() to disambiguate. -PyObject * -_Py_Offer_Suggestions(PyObject *exception) -{ - PyObject *result = NULL; - assert(!PyErr_Occurred()); - if (Py_IS_TYPE(exception, (PyTypeObject*)PyExc_AttributeError)) { - result = offer_suggestions_for_attribute_error((PyAttributeErrorObject *) exception); - } else if (Py_IS_TYPE(exception, (PyTypeObject*)PyExc_NameError)) { - result = offer_suggestions_for_name_error((PyNameErrorObject *) exception); - } - return result; -} - -Py_ssize_t -_Py_UTF8_Edit_Cost(PyObject *a, PyObject *b, Py_ssize_t max_cost) -{ - assert(PyUnicode_Check(a) && PyUnicode_Check(b)); - Py_ssize_t size_a, size_b; - const char *utf8_a = PyUnicode_AsUTF8AndSize(a, &size_a); - if (utf8_a == NULL) { - return -1; - } - const char *utf8_b = PyUnicode_AsUTF8AndSize(b, &size_b); - if (utf8_b == NULL) { - return -1; - } - if (max_cost == -1) { - max_cost = MOVE_COST * Py_MAX(size_a, size_b); - } - return levenshtein_distance(utf8_a, size_a, utf8_b, size_b, max_cost); -} - diff --git a/contrib/tools/python3/src/Python/symtable.c b/contrib/tools/python3/src/Python/symtable.c deleted file mode 100644 index 07f9d1132c7..00000000000 --- a/contrib/tools/python3/src/Python/symtable.c +++ /dev/null @@ -1,2161 +0,0 @@ -#include "Python.h" -#include "pycore_ast.h" // identifier, stmt_ty -#include "pycore_compile.h" // _Py_Mangle(), _PyFuture_FromAST() -#include "pycore_parser.h" // _PyParser_ASTFromString() -#include "pycore_pystate.h" // _PyThreadState_GET() -#include "pycore_symtable.h" // PySTEntryObject -#include "structmember.h" // PyMemberDef - -/* error strings used for warnings */ -#define GLOBAL_PARAM \ -"name '%U' is parameter and global" - -#define NONLOCAL_PARAM \ -"name '%U' is parameter and nonlocal" - -#define GLOBAL_AFTER_ASSIGN \ -"name '%U' is assigned to before global declaration" - -#define NONLOCAL_AFTER_ASSIGN \ -"name '%U' is assigned to before nonlocal declaration" - -#define GLOBAL_AFTER_USE \ -"name '%U' is used prior to global declaration" - -#define NONLOCAL_AFTER_USE \ -"name '%U' is used prior to nonlocal declaration" - -#define GLOBAL_ANNOT \ -"annotated name '%U' can't be global" - -#define NONLOCAL_ANNOT \ -"annotated name '%U' can't be nonlocal" - -#define IMPORT_STAR_WARNING "import * only allowed at module level" - -#define NAMED_EXPR_COMP_IN_CLASS \ -"assignment expression within a comprehension cannot be used in a class body" - -#define NAMED_EXPR_COMP_CONFLICT \ -"assignment expression cannot rebind comprehension iteration variable '%U'" - -#define NAMED_EXPR_COMP_INNER_LOOP_CONFLICT \ -"comprehension inner loop cannot rebind assignment expression target '%U'" - -#define NAMED_EXPR_COMP_ITER_EXPR \ -"assignment expression cannot be used in a comprehension iterable expression" - -#define ANNOTATION_NOT_ALLOWED \ -"'%s' can not be used within an annotation" - - -#define LOCATION(x) \ - (x)->lineno, (x)->col_offset, (x)->end_lineno, (x)->end_col_offset - -#define ST_LOCATION(x) \ - (x)->ste_lineno, (x)->ste_col_offset, (x)->ste_end_lineno, (x)->ste_end_col_offset - -static PySTEntryObject * -ste_new(struct symtable *st, identifier name, _Py_block_ty block, - void *key, int lineno, int col_offset, - int end_lineno, int end_col_offset) -{ - PySTEntryObject *ste = NULL; - PyObject *k = NULL; - - k = PyLong_FromVoidPtr(key); - if (k == NULL) - goto fail; - ste = PyObject_New(PySTEntryObject, &PySTEntry_Type); - if (ste == NULL) { - Py_DECREF(k); - goto fail; - } - ste->ste_table = st; - ste->ste_id = k; /* ste owns reference to k */ - - Py_INCREF(name); - ste->ste_name = name; - - ste->ste_symbols = NULL; - ste->ste_varnames = NULL; - ste->ste_children = NULL; - - ste->ste_directives = NULL; - - ste->ste_type = block; - ste->ste_nested = 0; - ste->ste_free = 0; - ste->ste_varargs = 0; - ste->ste_varkeywords = 0; - ste->ste_opt_lineno = 0; - ste->ste_opt_col_offset = 0; - ste->ste_lineno = lineno; - ste->ste_col_offset = col_offset; - ste->ste_end_lineno = end_lineno; - ste->ste_end_col_offset = end_col_offset; - - if (st->st_cur != NULL && - (st->st_cur->ste_nested || - st->st_cur->ste_type == FunctionBlock)) - ste->ste_nested = 1; - ste->ste_child_free = 0; - ste->ste_generator = 0; - ste->ste_coroutine = 0; - ste->ste_comprehension = NoComprehension; - ste->ste_returns_value = 0; - ste->ste_needs_class_closure = 0; - ste->ste_comp_iter_target = 0; - ste->ste_comp_iter_expr = 0; - - ste->ste_symbols = PyDict_New(); - ste->ste_varnames = PyList_New(0); - ste->ste_children = PyList_New(0); - if (ste->ste_symbols == NULL - || ste->ste_varnames == NULL - || ste->ste_children == NULL) - goto fail; - - if (PyDict_SetItem(st->st_blocks, ste->ste_id, (PyObject *)ste) < 0) - goto fail; - - return ste; - fail: - Py_XDECREF(ste); - return NULL; -} - -static PyObject * -ste_repr(PySTEntryObject *ste) -{ - return PyUnicode_FromFormat("<symtable entry %U(%ld), line %d>", - ste->ste_name, - PyLong_AS_LONG(ste->ste_id), ste->ste_lineno); -} - -static void -ste_dealloc(PySTEntryObject *ste) -{ - ste->ste_table = NULL; - Py_XDECREF(ste->ste_id); - Py_XDECREF(ste->ste_name); - Py_XDECREF(ste->ste_symbols); - Py_XDECREF(ste->ste_varnames); - Py_XDECREF(ste->ste_children); - Py_XDECREF(ste->ste_directives); - PyObject_Free(ste); -} - -#define OFF(x) offsetof(PySTEntryObject, x) - -static PyMemberDef ste_memberlist[] = { - {"id", T_OBJECT, OFF(ste_id), READONLY}, - {"name", T_OBJECT, OFF(ste_name), READONLY}, - {"symbols", T_OBJECT, OFF(ste_symbols), READONLY}, - {"varnames", T_OBJECT, OFF(ste_varnames), READONLY}, - {"children", T_OBJECT, OFF(ste_children), READONLY}, - {"nested", T_INT, OFF(ste_nested), READONLY}, - {"type", T_INT, OFF(ste_type), READONLY}, - {"lineno", T_INT, OFF(ste_lineno), READONLY}, - {NULL} -}; - -PyTypeObject PySTEntry_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "symtable entry", - sizeof(PySTEntryObject), - 0, - (destructor)ste_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - (reprfunc)ste_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ - 0, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - ste_memberlist, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ -}; - -static int symtable_analyze(struct symtable *st); -static int symtable_enter_block(struct symtable *st, identifier name, - _Py_block_ty block, void *ast, - int lineno, int col_offset, - int end_lineno, int end_col_offset); -static int symtable_exit_block(struct symtable *st); -static int symtable_visit_stmt(struct symtable *st, stmt_ty s); -static int symtable_visit_expr(struct symtable *st, expr_ty s); -static int symtable_visit_genexp(struct symtable *st, expr_ty s); -static int symtable_visit_listcomp(struct symtable *st, expr_ty s); -static int symtable_visit_setcomp(struct symtable *st, expr_ty s); -static int symtable_visit_dictcomp(struct symtable *st, expr_ty s); -static int symtable_visit_arguments(struct symtable *st, arguments_ty); -static int symtable_visit_excepthandler(struct symtable *st, excepthandler_ty); -static int symtable_visit_alias(struct symtable *st, alias_ty); -static int symtable_visit_comprehension(struct symtable *st, comprehension_ty); -static int symtable_visit_keyword(struct symtable *st, keyword_ty); -static int symtable_visit_params(struct symtable *st, asdl_arg_seq *args); -static int symtable_visit_annotation(struct symtable *st, expr_ty annotation); -static int symtable_visit_argannotations(struct symtable *st, asdl_arg_seq *args); -static int symtable_implicit_arg(struct symtable *st, int pos); -static int symtable_visit_annotations(struct symtable *st, stmt_ty, arguments_ty, expr_ty); -static int symtable_visit_withitem(struct symtable *st, withitem_ty item); -static int symtable_visit_match_case(struct symtable *st, match_case_ty m); -static int symtable_visit_pattern(struct symtable *st, pattern_ty s); -static int symtable_raise_if_annotation_block(struct symtable *st, const char *, expr_ty); -static int symtable_raise_if_comprehension_block(struct symtable *st, expr_ty); - - -static identifier top = NULL, lambda = NULL, genexpr = NULL, - listcomp = NULL, setcomp = NULL, dictcomp = NULL, - __class__ = NULL, _annotation = NULL; - -#define GET_IDENTIFIER(VAR) \ - ((VAR) ? (VAR) : ((VAR) = PyUnicode_InternFromString(# VAR))) - -#define DUPLICATE_ARGUMENT \ -"duplicate argument '%U' in function definition" - -static struct symtable * -symtable_new(void) -{ - struct symtable *st; - - st = (struct symtable *)PyMem_Malloc(sizeof(struct symtable)); - if (st == NULL) { - PyErr_NoMemory(); - return NULL; - } - - st->st_filename = NULL; - st->st_blocks = NULL; - - if ((st->st_stack = PyList_New(0)) == NULL) - goto fail; - if ((st->st_blocks = PyDict_New()) == NULL) - goto fail; - st->st_cur = NULL; - st->st_private = NULL; - return st; - fail: - _PySymtable_Free(st); - return NULL; -} - -/* When compiling the use of C stack is probably going to be a lot - lighter than when executing Python code but still can overflow - and causing a Python crash if not checked (e.g. eval("()"*300000)). - Using the current recursion limit for the compiler seems too - restrictive (it caused at least one test to fail) so a factor is - used to allow deeper recursion when compiling an expression. - - Using a scaling factor means this should automatically adjust when - the recursion limit is adjusted for small or large C stack allocations. -*/ -#define COMPILER_STACK_FRAME_SCALE 3 - -struct symtable * -_PySymtable_Build(mod_ty mod, PyObject *filename, PyFutureFeatures *future) -{ - struct symtable *st = symtable_new(); - asdl_stmt_seq *seq; - int i; - PyThreadState *tstate; - int recursion_limit = Py_GetRecursionLimit(); - int starting_recursion_depth; - - if (st == NULL) - return NULL; - if (filename == NULL) { - _PySymtable_Free(st); - return NULL; - } - Py_INCREF(filename); - st->st_filename = filename; - st->st_future = future; - - /* Setup recursion depth check counters */ - tstate = _PyThreadState_GET(); - if (!tstate) { - _PySymtable_Free(st); - return NULL; - } - /* Be careful here to prevent overflow. */ - starting_recursion_depth = (tstate->recursion_depth < INT_MAX / COMPILER_STACK_FRAME_SCALE) ? - tstate->recursion_depth * COMPILER_STACK_FRAME_SCALE : tstate->recursion_depth; - st->recursion_depth = starting_recursion_depth; - st->recursion_limit = (recursion_limit < INT_MAX / COMPILER_STACK_FRAME_SCALE) ? - recursion_limit * COMPILER_STACK_FRAME_SCALE : recursion_limit; - - /* Make the initial symbol information gathering pass */ - if (!GET_IDENTIFIER(top) || - !symtable_enter_block(st, top, ModuleBlock, (void *)mod, 0, 0, 0, 0)) { - _PySymtable_Free(st); - return NULL; - } - - st->st_top = st->st_cur; - switch (mod->kind) { - case Module_kind: - seq = mod->v.Module.body; - for (i = 0; i < asdl_seq_LEN(seq); i++) - if (!symtable_visit_stmt(st, - (stmt_ty)asdl_seq_GET(seq, i))) - goto error; - break; - case Expression_kind: - if (!symtable_visit_expr(st, mod->v.Expression.body)) - goto error; - break; - case Interactive_kind: - seq = mod->v.Interactive.body; - for (i = 0; i < asdl_seq_LEN(seq); i++) - if (!symtable_visit_stmt(st, - (stmt_ty)asdl_seq_GET(seq, i))) - goto error; - break; - case FunctionType_kind: - PyErr_SetString(PyExc_RuntimeError, - "this compiler does not handle FunctionTypes"); - goto error; - } - if (!symtable_exit_block(st)) { - _PySymtable_Free(st); - return NULL; - } - /* Check that the recursion depth counting balanced correctly */ - if (st->recursion_depth != starting_recursion_depth) { - PyErr_Format(PyExc_SystemError, - "symtable analysis recursion depth mismatch (before=%d, after=%d)", - starting_recursion_depth, st->recursion_depth); - _PySymtable_Free(st); - return NULL; - } - /* Make the second symbol analysis pass */ - if (symtable_analyze(st)) - return st; - _PySymtable_Free(st); - return NULL; - error: - (void) symtable_exit_block(st); - _PySymtable_Free(st); - return NULL; -} - - -void -_PySymtable_Free(struct symtable *st) -{ - Py_XDECREF(st->st_filename); - Py_XDECREF(st->st_blocks); - Py_XDECREF(st->st_stack); - PyMem_Free((void *)st); -} - -PySTEntryObject * -PySymtable_Lookup(struct symtable *st, void *key) -{ - PyObject *k, *v; - - k = PyLong_FromVoidPtr(key); - if (k == NULL) - return NULL; - v = PyDict_GetItemWithError(st->st_blocks, k); - if (v) { - assert(PySTEntry_Check(v)); - Py_INCREF(v); - } - else if (!PyErr_Occurred()) { - PyErr_SetString(PyExc_KeyError, - "unknown symbol table entry"); - } - - Py_DECREF(k); - return (PySTEntryObject *)v; -} - -static long -_PyST_GetSymbol(PySTEntryObject *ste, PyObject *name) -{ - PyObject *v = PyDict_GetItemWithError(ste->ste_symbols, name); - if (!v) - return 0; - assert(PyLong_Check(v)); - return PyLong_AS_LONG(v); -} - -int -_PyST_GetScope(PySTEntryObject *ste, PyObject *name) -{ - long symbol = _PyST_GetSymbol(ste, name); - return (symbol >> SCOPE_OFFSET) & SCOPE_MASK; -} - -static int -error_at_directive(PySTEntryObject *ste, PyObject *name) -{ - Py_ssize_t i; - PyObject *data; - assert(ste->ste_directives); - for (i = 0; i < PyList_GET_SIZE(ste->ste_directives); i++) { - data = PyList_GET_ITEM(ste->ste_directives, i); - assert(PyTuple_CheckExact(data)); - assert(PyUnicode_CheckExact(PyTuple_GET_ITEM(data, 0))); - if (PyUnicode_Compare(PyTuple_GET_ITEM(data, 0), name) == 0) { - PyErr_RangedSyntaxLocationObject(ste->ste_table->st_filename, - PyLong_AsLong(PyTuple_GET_ITEM(data, 1)), - PyLong_AsLong(PyTuple_GET_ITEM(data, 2)) + 1, - PyLong_AsLong(PyTuple_GET_ITEM(data, 3)), - PyLong_AsLong(PyTuple_GET_ITEM(data, 4)) + 1); - - return 0; - } - } - PyErr_SetString(PyExc_RuntimeError, - "BUG: internal directive bookkeeping broken"); - return 0; -} - - -/* Analyze raw symbol information to determine scope of each name. - - The next several functions are helpers for symtable_analyze(), - which determines whether a name is local, global, or free. In addition, - it determines which local variables are cell variables; they provide - bindings that are used for free variables in enclosed blocks. - - There are also two kinds of global variables, implicit and explicit. An - explicit global is declared with the global statement. An implicit - global is a free variable for which the compiler has found no binding - in an enclosing function scope. The implicit global is either a global - or a builtin. Python's module and class blocks use the xxx_NAME opcodes - to handle these names to implement slightly odd semantics. In such a - block, the name is treated as global until it is assigned to; then it - is treated as a local. - - The symbol table requires two passes to determine the scope of each name. - The first pass collects raw facts from the AST via the symtable_visit_* - functions: the name is a parameter here, the name is used but not defined - here, etc. The second pass analyzes these facts during a pass over the - PySTEntryObjects created during pass 1. - - When a function is entered during the second pass, the parent passes - the set of all name bindings visible to its children. These bindings - are used to determine if non-local variables are free or implicit globals. - Names which are explicitly declared nonlocal must exist in this set of - visible names - if they do not, a syntax error is raised. After doing - the local analysis, it analyzes each of its child blocks using an - updated set of name bindings. - - The children update the free variable set. If a local variable is added to - the free variable set by the child, the variable is marked as a cell. The - function object being defined must provide runtime storage for the variable - that may outlive the function's frame. Cell variables are removed from the - free set before the analyze function returns to its parent. - - During analysis, the names are: - symbols: dict mapping from symbol names to flag values (including offset scope values) - scopes: dict mapping from symbol names to scope values (no offset) - local: set of all symbol names local to the current scope - bound: set of all symbol names local to a containing function scope - free: set of all symbol names referenced but not bound in child scopes - global: set of all symbol names explicitly declared as global -*/ - -#define SET_SCOPE(DICT, NAME, I) { \ - PyObject *o = PyLong_FromLong(I); \ - if (!o) \ - return 0; \ - if (PyDict_SetItem((DICT), (NAME), o) < 0) { \ - Py_DECREF(o); \ - return 0; \ - } \ - Py_DECREF(o); \ -} - -/* Decide on scope of name, given flags. - - The namespace dictionaries may be modified to record information - about the new name. For example, a new global will add an entry to - global. A name that was global can be changed to local. -*/ - -static int -analyze_name(PySTEntryObject *ste, PyObject *scopes, PyObject *name, long flags, - PyObject *bound, PyObject *local, PyObject *free, - PyObject *global) -{ - if (flags & DEF_GLOBAL) { - if (flags & DEF_NONLOCAL) { - PyErr_Format(PyExc_SyntaxError, - "name '%U' is nonlocal and global", - name); - return error_at_directive(ste, name); - } - SET_SCOPE(scopes, name, GLOBAL_EXPLICIT); - if (PySet_Add(global, name) < 0) - return 0; - if (bound && (PySet_Discard(bound, name) < 0)) - return 0; - return 1; - } - if (flags & DEF_NONLOCAL) { - if (!bound) { - PyErr_Format(PyExc_SyntaxError, - "nonlocal declaration not allowed at module level"); - return error_at_directive(ste, name); - } - if (!PySet_Contains(bound, name)) { - PyErr_Format(PyExc_SyntaxError, - "no binding for nonlocal '%U' found", - name); - - return error_at_directive(ste, name); - } - SET_SCOPE(scopes, name, FREE); - ste->ste_free = 1; - return PySet_Add(free, name) >= 0; - } - if (flags & DEF_BOUND) { - SET_SCOPE(scopes, name, LOCAL); - if (PySet_Add(local, name) < 0) - return 0; - if (PySet_Discard(global, name) < 0) - return 0; - return 1; - } - /* If an enclosing block has a binding for this name, it - is a free variable rather than a global variable. - Note that having a non-NULL bound implies that the block - is nested. - */ - if (bound && PySet_Contains(bound, name)) { - SET_SCOPE(scopes, name, FREE); - ste->ste_free = 1; - return PySet_Add(free, name) >= 0; - } - /* If a parent has a global statement, then call it global - explicit? It could also be global implicit. - */ - if (global && PySet_Contains(global, name)) { - SET_SCOPE(scopes, name, GLOBAL_IMPLICIT); - return 1; - } - if (ste->ste_nested) - ste->ste_free = 1; - SET_SCOPE(scopes, name, GLOBAL_IMPLICIT); - return 1; -} - -#undef SET_SCOPE - -/* If a name is defined in free and also in locals, then this block - provides the binding for the free variable. The name should be - marked CELL in this block and removed from the free list. - - Note that the current block's free variables are included in free. - That's safe because no name can be free and local in the same scope. -*/ - -static int -analyze_cells(PyObject *scopes, PyObject *free) -{ - PyObject *name, *v, *v_cell; - int success = 0; - Py_ssize_t pos = 0; - - v_cell = PyLong_FromLong(CELL); - if (!v_cell) - return 0; - while (PyDict_Next(scopes, &pos, &name, &v)) { - long scope; - assert(PyLong_Check(v)); - scope = PyLong_AS_LONG(v); - if (scope != LOCAL) - continue; - if (!PySet_Contains(free, name)) - continue; - /* Replace LOCAL with CELL for this name, and remove - from free. It is safe to replace the value of name - in the dict, because it will not cause a resize. - */ - if (PyDict_SetItem(scopes, name, v_cell) < 0) - goto error; - if (PySet_Discard(free, name) < 0) - goto error; - } - success = 1; - error: - Py_DECREF(v_cell); - return success; -} - -static int -drop_class_free(PySTEntryObject *ste, PyObject *free) -{ - int res; - if (!GET_IDENTIFIER(__class__)) - return 0; - res = PySet_Discard(free, __class__); - if (res < 0) - return 0; - if (res) - ste->ste_needs_class_closure = 1; - return 1; -} - -/* Enter the final scope information into the ste_symbols dict. - * - * All arguments are dicts. Modifies symbols, others are read-only. -*/ -static int -update_symbols(PyObject *symbols, PyObject *scopes, - PyObject *bound, PyObject *free, int classflag) -{ - PyObject *name = NULL, *itr = NULL; - PyObject *v = NULL, *v_scope = NULL, *v_new = NULL, *v_free = NULL; - Py_ssize_t pos = 0; - - /* Update scope information for all symbols in this scope */ - while (PyDict_Next(symbols, &pos, &name, &v)) { - long scope, flags; - assert(PyLong_Check(v)); - flags = PyLong_AS_LONG(v); - v_scope = PyDict_GetItemWithError(scopes, name); - assert(v_scope && PyLong_Check(v_scope)); - scope = PyLong_AS_LONG(v_scope); - flags |= (scope << SCOPE_OFFSET); - v_new = PyLong_FromLong(flags); - if (!v_new) - return 0; - if (PyDict_SetItem(symbols, name, v_new) < 0) { - Py_DECREF(v_new); - return 0; - } - Py_DECREF(v_new); - } - - /* Record not yet resolved free variables from children (if any) */ - v_free = PyLong_FromLong(FREE << SCOPE_OFFSET); - if (!v_free) - return 0; - - itr = PyObject_GetIter(free); - if (itr == NULL) { - Py_DECREF(v_free); - return 0; - } - - while ((name = PyIter_Next(itr))) { - v = PyDict_GetItemWithError(symbols, name); - - /* Handle symbol that already exists in this scope */ - if (v) { - /* Handle a free variable in a method of - the class that has the same name as a local - or global in the class scope. - */ - if (classflag && - PyLong_AS_LONG(v) & (DEF_BOUND | DEF_GLOBAL)) { - long flags = PyLong_AS_LONG(v) | DEF_FREE_CLASS; - v_new = PyLong_FromLong(flags); - if (!v_new) { - goto error; - } - if (PyDict_SetItem(symbols, name, v_new) < 0) { - Py_DECREF(v_new); - goto error; - } - Py_DECREF(v_new); - } - /* It's a cell, or already free in this scope */ - Py_DECREF(name); - continue; - } - else if (PyErr_Occurred()) { - goto error; - } - /* Handle global symbol */ - if (bound && !PySet_Contains(bound, name)) { - Py_DECREF(name); - continue; /* it's a global */ - } - /* Propagate new free symbol up the lexical stack */ - if (PyDict_SetItem(symbols, name, v_free) < 0) { - goto error; - } - Py_DECREF(name); - } - Py_DECREF(itr); - Py_DECREF(v_free); - return 1; -error: - Py_XDECREF(v_free); - Py_XDECREF(itr); - Py_XDECREF(name); - return 0; -} - -/* Make final symbol table decisions for block of ste. - - Arguments: - ste -- current symtable entry (input/output) - bound -- set of variables bound in enclosing scopes (input). bound - is NULL for module blocks. - free -- set of free variables in enclosed scopes (output) - globals -- set of declared global variables in enclosing scopes (input) - - The implementation uses two mutually recursive functions, - analyze_block() and analyze_child_block(). analyze_block() is - responsible for analyzing the individual names defined in a block. - analyze_child_block() prepares temporary namespace dictionaries - used to evaluated nested blocks. - - The two functions exist because a child block should see the name - bindings of its enclosing blocks, but those bindings should not - propagate back to a parent block. -*/ - -static int -analyze_child_block(PySTEntryObject *entry, PyObject *bound, PyObject *free, - PyObject *global, PyObject* child_free); - -static int -analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free, - PyObject *global) -{ - PyObject *name, *v, *local = NULL, *scopes = NULL, *newbound = NULL; - PyObject *newglobal = NULL, *newfree = NULL, *allfree = NULL; - PyObject *temp; - int i, success = 0; - Py_ssize_t pos = 0; - - local = PySet_New(NULL); /* collect new names bound in block */ - if (!local) - goto error; - scopes = PyDict_New(); /* collect scopes defined for each name */ - if (!scopes) - goto error; - - /* Allocate new global and bound variable dictionaries. These - dictionaries hold the names visible in nested blocks. For - ClassBlocks, the bound and global names are initialized - before analyzing names, because class bindings aren't - visible in methods. For other blocks, they are initialized - after names are analyzed. - */ - - /* TODO(jhylton): Package these dicts in a struct so that we - can write reasonable helper functions? - */ - newglobal = PySet_New(NULL); - if (!newglobal) - goto error; - newfree = PySet_New(NULL); - if (!newfree) - goto error; - newbound = PySet_New(NULL); - if (!newbound) - goto error; - - /* Class namespace has no effect on names visible in - nested functions, so populate the global and bound - sets to be passed to child blocks before analyzing - this one. - */ - if (ste->ste_type == ClassBlock) { - /* Pass down known globals */ - temp = PyNumber_InPlaceOr(newglobal, global); - if (!temp) - goto error; - Py_DECREF(temp); - /* Pass down previously bound symbols */ - if (bound) { - temp = PyNumber_InPlaceOr(newbound, bound); - if (!temp) - goto error; - Py_DECREF(temp); - } - } - - while (PyDict_Next(ste->ste_symbols, &pos, &name, &v)) { - long flags = PyLong_AS_LONG(v); - if (!analyze_name(ste, scopes, name, flags, - bound, local, free, global)) - goto error; - } - - /* Populate global and bound sets to be passed to children. */ - if (ste->ste_type != ClassBlock) { - /* Add function locals to bound set */ - if (ste->ste_type == FunctionBlock) { - temp = PyNumber_InPlaceOr(newbound, local); - if (!temp) - goto error; - Py_DECREF(temp); - } - /* Pass down previously bound symbols */ - if (bound) { - temp = PyNumber_InPlaceOr(newbound, bound); - if (!temp) - goto error; - Py_DECREF(temp); - } - /* Pass down known globals */ - temp = PyNumber_InPlaceOr(newglobal, global); - if (!temp) - goto error; - Py_DECREF(temp); - } - else { - /* Special-case __class__ */ - if (!GET_IDENTIFIER(__class__)) - goto error; - if (PySet_Add(newbound, __class__) < 0) - goto error; - } - - /* Recursively call analyze_child_block() on each child block. - - newbound, newglobal now contain the names visible in - nested blocks. The free variables in the children will - be collected in allfree. - */ - allfree = PySet_New(NULL); - if (!allfree) - goto error; - for (i = 0; i < PyList_GET_SIZE(ste->ste_children); ++i) { - PyObject *c = PyList_GET_ITEM(ste->ste_children, i); - PySTEntryObject* entry; - assert(c && PySTEntry_Check(c)); - entry = (PySTEntryObject*)c; - if (!analyze_child_block(entry, newbound, newfree, newglobal, - allfree)) - goto error; - /* Check if any children have free variables */ - if (entry->ste_free || entry->ste_child_free) - ste->ste_child_free = 1; - } - - temp = PyNumber_InPlaceOr(newfree, allfree); - if (!temp) - goto error; - Py_DECREF(temp); - - /* Check if any local variables must be converted to cell variables */ - if (ste->ste_type == FunctionBlock && !analyze_cells(scopes, newfree)) - goto error; - else if (ste->ste_type == ClassBlock && !drop_class_free(ste, newfree)) - goto error; - /* Records the results of the analysis in the symbol table entry */ - if (!update_symbols(ste->ste_symbols, scopes, bound, newfree, - ste->ste_type == ClassBlock)) - goto error; - - temp = PyNumber_InPlaceOr(free, newfree); - if (!temp) - goto error; - Py_DECREF(temp); - success = 1; - error: - Py_XDECREF(scopes); - Py_XDECREF(local); - Py_XDECREF(newbound); - Py_XDECREF(newglobal); - Py_XDECREF(newfree); - Py_XDECREF(allfree); - if (!success) - assert(PyErr_Occurred()); - return success; -} - -static int -analyze_child_block(PySTEntryObject *entry, PyObject *bound, PyObject *free, - PyObject *global, PyObject* child_free) -{ - PyObject *temp_bound = NULL, *temp_global = NULL, *temp_free = NULL; - PyObject *temp; - - /* Copy the bound and global dictionaries. - - These dictionaries are used by all blocks enclosed by the - current block. The analyze_block() call modifies these - dictionaries. - - */ - temp_bound = PySet_New(bound); - if (!temp_bound) - goto error; - temp_free = PySet_New(free); - if (!temp_free) - goto error; - temp_global = PySet_New(global); - if (!temp_global) - goto error; - - if (!analyze_block(entry, temp_bound, temp_free, temp_global)) - goto error; - temp = PyNumber_InPlaceOr(child_free, temp_free); - if (!temp) - goto error; - Py_DECREF(temp); - Py_DECREF(temp_bound); - Py_DECREF(temp_free); - Py_DECREF(temp_global); - return 1; - error: - Py_XDECREF(temp_bound); - Py_XDECREF(temp_free); - Py_XDECREF(temp_global); - return 0; -} - -static int -symtable_analyze(struct symtable *st) -{ - PyObject *free, *global; - int r; - - free = PySet_New(NULL); - if (!free) - return 0; - global = PySet_New(NULL); - if (!global) { - Py_DECREF(free); - return 0; - } - r = analyze_block(st->st_top, NULL, free, global); - Py_DECREF(free); - Py_DECREF(global); - return r; -} - -/* symtable_enter_block() gets a reference via ste_new. - This reference is released when the block is exited, via the DECREF - in symtable_exit_block(). -*/ - -static int -symtable_exit_block(struct symtable *st) -{ - Py_ssize_t size; - - st->st_cur = NULL; - size = PyList_GET_SIZE(st->st_stack); - if (size) { - if (PyList_SetSlice(st->st_stack, size - 1, size, NULL) < 0) - return 0; - if (--size) - st->st_cur = (PySTEntryObject *)PyList_GET_ITEM(st->st_stack, size - 1); - } - return 1; -} - -static int -symtable_enter_block(struct symtable *st, identifier name, _Py_block_ty block, - void *ast, int lineno, int col_offset, - int end_lineno, int end_col_offset) -{ - PySTEntryObject *prev = NULL, *ste; - - ste = ste_new(st, name, block, ast, lineno, col_offset, end_lineno, end_col_offset); - if (ste == NULL) - return 0; - if (PyList_Append(st->st_stack, (PyObject *)ste) < 0) { - Py_DECREF(ste); - return 0; - } - prev = st->st_cur; - /* bpo-37757: For now, disallow *all* assignment expressions in the - * outermost iterator expression of a comprehension, even those inside - * a nested comprehension or a lambda expression. - */ - if (prev) { - ste->ste_comp_iter_expr = prev->ste_comp_iter_expr; - } - /* The entry is owned by the stack. Borrow it for st_cur. */ - Py_DECREF(ste); - st->st_cur = ste; - - /* Annotation blocks shouldn't have any affect on the symbol table since in - * the compilation stage, they will all be transformed to strings. They are - * only created if future 'annotations' feature is activated. */ - if (block == AnnotationBlock) { - return 1; - } - - if (block == ModuleBlock) - st->st_global = st->st_cur->ste_symbols; - - if (prev) { - if (PyList_Append(prev->ste_children, (PyObject *)ste) < 0) { - return 0; - } - } - return 1; -} - -static long -symtable_lookup(struct symtable *st, PyObject *name) -{ - PyObject *mangled = _Py_Mangle(st->st_private, name); - if (!mangled) - return 0; - long ret = _PyST_GetSymbol(st->st_cur, mangled); - Py_DECREF(mangled); - return ret; -} - -static int -symtable_add_def_helper(struct symtable *st, PyObject *name, int flag, struct _symtable_entry *ste, - int lineno, int col_offset, int end_lineno, int end_col_offset) -{ - PyObject *o; - PyObject *dict; - long val; - PyObject *mangled = _Py_Mangle(st->st_private, name); - - - if (!mangled) - return 0; - dict = ste->ste_symbols; - if ((o = PyDict_GetItemWithError(dict, mangled))) { - val = PyLong_AS_LONG(o); - if ((flag & DEF_PARAM) && (val & DEF_PARAM)) { - /* Is it better to use 'mangled' or 'name' here? */ - PyErr_Format(PyExc_SyntaxError, DUPLICATE_ARGUMENT, name); - PyErr_RangedSyntaxLocationObject(st->st_filename, - lineno, col_offset + 1, - end_lineno, end_col_offset + 1); - goto error; - } - val |= flag; - } - else if (PyErr_Occurred()) { - goto error; - } - else { - val = flag; - } - if (ste->ste_comp_iter_target) { - /* This name is an iteration variable in a comprehension, - * so check for a binding conflict with any named expressions. - * Otherwise, mark it as an iteration variable so subsequent - * named expressions can check for conflicts. - */ - if (val & (DEF_GLOBAL | DEF_NONLOCAL)) { - PyErr_Format(PyExc_SyntaxError, - NAMED_EXPR_COMP_INNER_LOOP_CONFLICT, name); - PyErr_RangedSyntaxLocationObject(st->st_filename, - lineno, col_offset + 1, - end_lineno, end_col_offset + 1); - goto error; - } - val |= DEF_COMP_ITER; - } - o = PyLong_FromLong(val); - if (o == NULL) - goto error; - if (PyDict_SetItem(dict, mangled, o) < 0) { - Py_DECREF(o); - goto error; - } - Py_DECREF(o); - - if (flag & DEF_PARAM) { - if (PyList_Append(ste->ste_varnames, mangled) < 0) - goto error; - } else if (flag & DEF_GLOBAL) { - /* XXX need to update DEF_GLOBAL for other flags too; - perhaps only DEF_FREE_GLOBAL */ - val = flag; - if ((o = PyDict_GetItemWithError(st->st_global, mangled))) { - val |= PyLong_AS_LONG(o); - } - else if (PyErr_Occurred()) { - goto error; - } - o = PyLong_FromLong(val); - if (o == NULL) - goto error; - if (PyDict_SetItem(st->st_global, mangled, o) < 0) { - Py_DECREF(o); - goto error; - } - Py_DECREF(o); - } - Py_DECREF(mangled); - return 1; - -error: - Py_DECREF(mangled); - return 0; -} - -static int -symtable_add_def(struct symtable *st, PyObject *name, int flag, - int lineno, int col_offset, int end_lineno, int end_col_offset) -{ - return symtable_add_def_helper(st, name, flag, st->st_cur, - lineno, col_offset, end_lineno, end_col_offset); -} - -/* VISIT, VISIT_SEQ and VIST_SEQ_TAIL take an ASDL type as their second argument. - They use the ASDL name to synthesize the name of the C type and the visit - function. - - VISIT_SEQ_TAIL permits the start of an ASDL sequence to be skipped, which is - useful if the first node in the sequence requires special treatment. - - VISIT_QUIT macro returns the specified value exiting from the function but - first adjusts current recursion counter depth. -*/ - -#define VISIT_QUIT(ST, X) \ - return --(ST)->recursion_depth,(X) - -#define VISIT(ST, TYPE, V) \ - if (!symtable_visit_ ## TYPE((ST), (V))) \ - VISIT_QUIT((ST), 0); - -#define VISIT_SEQ(ST, TYPE, SEQ) { \ - int i; \ - asdl_ ## TYPE ## _seq *seq = (SEQ); /* avoid variable capture */ \ - for (i = 0; i < asdl_seq_LEN(seq); i++) { \ - TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, i); \ - if (!symtable_visit_ ## TYPE((ST), elt)) \ - VISIT_QUIT((ST), 0); \ - } \ -} - -#define VISIT_SEQ_TAIL(ST, TYPE, SEQ, START) { \ - int i; \ - asdl_ ## TYPE ## _seq *seq = (SEQ); /* avoid variable capture */ \ - for (i = (START); i < asdl_seq_LEN(seq); i++) { \ - TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, i); \ - if (!symtable_visit_ ## TYPE((ST), elt)) \ - VISIT_QUIT((ST), 0); \ - } \ -} - -#define VISIT_SEQ_WITH_NULL(ST, TYPE, SEQ) { \ - int i = 0; \ - asdl_ ## TYPE ## _seq *seq = (SEQ); /* avoid variable capture */ \ - for (i = 0; i < asdl_seq_LEN(seq); i++) { \ - TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, i); \ - if (!elt) continue; /* can be NULL */ \ - if (!symtable_visit_ ## TYPE((ST), elt)) \ - VISIT_QUIT((ST), 0); \ - } \ -} - -static int -symtable_record_directive(struct symtable *st, identifier name, int lineno, - int col_offset, int end_lineno, int end_col_offset) -{ - PyObject *data, *mangled; - int res; - if (!st->st_cur->ste_directives) { - st->st_cur->ste_directives = PyList_New(0); - if (!st->st_cur->ste_directives) - return 0; - } - mangled = _Py_Mangle(st->st_private, name); - if (!mangled) - return 0; - data = Py_BuildValue("(Niiii)", mangled, lineno, col_offset, end_lineno, end_col_offset); - if (!data) - return 0; - res = PyList_Append(st->st_cur->ste_directives, data); - Py_DECREF(data); - return res == 0; -} - - -static int -symtable_visit_stmt(struct symtable *st, stmt_ty s) -{ - if (++st->recursion_depth > st->recursion_limit) { - PyErr_SetString(PyExc_RecursionError, - "maximum recursion depth exceeded during compilation"); - VISIT_QUIT(st, 0); - } - switch (s->kind) { - case FunctionDef_kind: - if (!symtable_add_def(st, s->v.FunctionDef.name, DEF_LOCAL, LOCATION(s))) - VISIT_QUIT(st, 0); - if (s->v.FunctionDef.args->defaults) - VISIT_SEQ(st, expr, s->v.FunctionDef.args->defaults); - if (s->v.FunctionDef.args->kw_defaults) - VISIT_SEQ_WITH_NULL(st, expr, s->v.FunctionDef.args->kw_defaults); - if (!symtable_visit_annotations(st, s, s->v.FunctionDef.args, - s->v.FunctionDef.returns)) - VISIT_QUIT(st, 0); - if (s->v.FunctionDef.decorator_list) - VISIT_SEQ(st, expr, s->v.FunctionDef.decorator_list); - if (!symtable_enter_block(st, s->v.FunctionDef.name, - FunctionBlock, (void *)s, - LOCATION(s))) - VISIT_QUIT(st, 0); - VISIT(st, arguments, s->v.FunctionDef.args); - VISIT_SEQ(st, stmt, s->v.FunctionDef.body); - if (!symtable_exit_block(st)) - VISIT_QUIT(st, 0); - break; - case ClassDef_kind: { - PyObject *tmp; - if (!symtable_add_def(st, s->v.ClassDef.name, DEF_LOCAL, LOCATION(s))) - VISIT_QUIT(st, 0); - VISIT_SEQ(st, expr, s->v.ClassDef.bases); - VISIT_SEQ(st, keyword, s->v.ClassDef.keywords); - if (s->v.ClassDef.decorator_list) - VISIT_SEQ(st, expr, s->v.ClassDef.decorator_list); - if (!symtable_enter_block(st, s->v.ClassDef.name, ClassBlock, - (void *)s, s->lineno, s->col_offset, - s->end_lineno, s->end_col_offset)) - VISIT_QUIT(st, 0); - tmp = st->st_private; - st->st_private = s->v.ClassDef.name; - VISIT_SEQ(st, stmt, s->v.ClassDef.body); - st->st_private = tmp; - if (!symtable_exit_block(st)) - VISIT_QUIT(st, 0); - break; - } - case Return_kind: - if (s->v.Return.value) { - VISIT(st, expr, s->v.Return.value); - st->st_cur->ste_returns_value = 1; - } - break; - case Delete_kind: - VISIT_SEQ(st, expr, s->v.Delete.targets); - break; - case Assign_kind: - VISIT_SEQ(st, expr, s->v.Assign.targets); - VISIT(st, expr, s->v.Assign.value); - break; - case AnnAssign_kind: - if (s->v.AnnAssign.target->kind == Name_kind) { - expr_ty e_name = s->v.AnnAssign.target; - long cur = symtable_lookup(st, e_name->v.Name.id); - if (cur < 0) { - VISIT_QUIT(st, 0); - } - if ((cur & (DEF_GLOBAL | DEF_NONLOCAL)) - && (st->st_cur->ste_symbols != st->st_global) - && s->v.AnnAssign.simple) { - PyErr_Format(PyExc_SyntaxError, - cur & DEF_GLOBAL ? GLOBAL_ANNOT : NONLOCAL_ANNOT, - e_name->v.Name.id); - PyErr_RangedSyntaxLocationObject(st->st_filename, - s->lineno, - s->col_offset + 1, - s->end_lineno, - s->end_col_offset + 1); - VISIT_QUIT(st, 0); - } - if (s->v.AnnAssign.simple && - !symtable_add_def(st, e_name->v.Name.id, - DEF_ANNOT | DEF_LOCAL, LOCATION(e_name))) { - VISIT_QUIT(st, 0); - } - else { - if (s->v.AnnAssign.value - && !symtable_add_def(st, e_name->v.Name.id, DEF_LOCAL, LOCATION(e_name))) { - VISIT_QUIT(st, 0); - } - } - } - else { - VISIT(st, expr, s->v.AnnAssign.target); - } - if (!symtable_visit_annotation(st, s->v.AnnAssign.annotation)) { - VISIT_QUIT(st, 0); - } - - if (s->v.AnnAssign.value) { - VISIT(st, expr, s->v.AnnAssign.value); - } - break; - case AugAssign_kind: - VISIT(st, expr, s->v.AugAssign.target); - VISIT(st, expr, s->v.AugAssign.value); - break; - case For_kind: - VISIT(st, expr, s->v.For.target); - VISIT(st, expr, s->v.For.iter); - VISIT_SEQ(st, stmt, s->v.For.body); - if (s->v.For.orelse) - VISIT_SEQ(st, stmt, s->v.For.orelse); - break; - case While_kind: - VISIT(st, expr, s->v.While.test); - VISIT_SEQ(st, stmt, s->v.While.body); - if (s->v.While.orelse) - VISIT_SEQ(st, stmt, s->v.While.orelse); - break; - case If_kind: - /* XXX if 0: and lookup_yield() hacks */ - VISIT(st, expr, s->v.If.test); - VISIT_SEQ(st, stmt, s->v.If.body); - if (s->v.If.orelse) - VISIT_SEQ(st, stmt, s->v.If.orelse); - break; - case Match_kind: - VISIT(st, expr, s->v.Match.subject); - VISIT_SEQ(st, match_case, s->v.Match.cases); - break; - case Raise_kind: - if (s->v.Raise.exc) { - VISIT(st, expr, s->v.Raise.exc); - if (s->v.Raise.cause) { - VISIT(st, expr, s->v.Raise.cause); - } - } - break; - case Try_kind: - VISIT_SEQ(st, stmt, s->v.Try.body); - VISIT_SEQ(st, stmt, s->v.Try.orelse); - VISIT_SEQ(st, excepthandler, s->v.Try.handlers); - VISIT_SEQ(st, stmt, s->v.Try.finalbody); - break; - case Assert_kind: - VISIT(st, expr, s->v.Assert.test); - if (s->v.Assert.msg) - VISIT(st, expr, s->v.Assert.msg); - break; - case Import_kind: - VISIT_SEQ(st, alias, s->v.Import.names); - break; - case ImportFrom_kind: - VISIT_SEQ(st, alias, s->v.ImportFrom.names); - break; - case Global_kind: { - int i; - asdl_identifier_seq *seq = s->v.Global.names; - for (i = 0; i < asdl_seq_LEN(seq); i++) { - identifier name = (identifier)asdl_seq_GET(seq, i); - long cur = symtable_lookup(st, name); - if (cur < 0) - VISIT_QUIT(st, 0); - if (cur & (DEF_PARAM | DEF_LOCAL | USE | DEF_ANNOT)) { - const char* msg; - if (cur & DEF_PARAM) { - msg = GLOBAL_PARAM; - } else if (cur & USE) { - msg = GLOBAL_AFTER_USE; - } else if (cur & DEF_ANNOT) { - msg = GLOBAL_ANNOT; - } else { /* DEF_LOCAL */ - msg = GLOBAL_AFTER_ASSIGN; - } - PyErr_Format(PyExc_SyntaxError, - msg, name); - PyErr_RangedSyntaxLocationObject(st->st_filename, - s->lineno, - s->col_offset + 1, - s->end_lineno, - s->end_col_offset + 1); - VISIT_QUIT(st, 0); - } - if (!symtable_add_def(st, name, DEF_GLOBAL, LOCATION(s))) - VISIT_QUIT(st, 0); - if (!symtable_record_directive(st, name, s->lineno, s->col_offset, - s->end_lineno, s->end_col_offset)) - VISIT_QUIT(st, 0); - } - break; - } - case Nonlocal_kind: { - int i; - asdl_identifier_seq *seq = s->v.Nonlocal.names; - for (i = 0; i < asdl_seq_LEN(seq); i++) { - identifier name = (identifier)asdl_seq_GET(seq, i); - long cur = symtable_lookup(st, name); - if (cur < 0) - VISIT_QUIT(st, 0); - if (cur & (DEF_PARAM | DEF_LOCAL | USE | DEF_ANNOT)) { - const char* msg; - if (cur & DEF_PARAM) { - msg = NONLOCAL_PARAM; - } else if (cur & USE) { - msg = NONLOCAL_AFTER_USE; - } else if (cur & DEF_ANNOT) { - msg = NONLOCAL_ANNOT; - } else { /* DEF_LOCAL */ - msg = NONLOCAL_AFTER_ASSIGN; - } - PyErr_Format(PyExc_SyntaxError, msg, name); - PyErr_RangedSyntaxLocationObject(st->st_filename, - s->lineno, - s->col_offset + 1, - s->end_lineno, - s->end_col_offset + 1); - VISIT_QUIT(st, 0); - } - if (!symtable_add_def(st, name, DEF_NONLOCAL, LOCATION(s))) - VISIT_QUIT(st, 0); - if (!symtable_record_directive(st, name, s->lineno, s->col_offset, - s->end_lineno, s->end_col_offset)) - VISIT_QUIT(st, 0); - } - break; - } - case Expr_kind: - VISIT(st, expr, s->v.Expr.value); - break; - case Pass_kind: - case Break_kind: - case Continue_kind: - /* nothing to do here */ - break; - case With_kind: - VISIT_SEQ(st, withitem, s->v.With.items); - VISIT_SEQ(st, stmt, s->v.With.body); - break; - case AsyncFunctionDef_kind: - if (!symtable_add_def(st, s->v.AsyncFunctionDef.name, DEF_LOCAL, LOCATION(s))) - VISIT_QUIT(st, 0); - if (s->v.AsyncFunctionDef.args->defaults) - VISIT_SEQ(st, expr, s->v.AsyncFunctionDef.args->defaults); - if (s->v.AsyncFunctionDef.args->kw_defaults) - VISIT_SEQ_WITH_NULL(st, expr, - s->v.AsyncFunctionDef.args->kw_defaults); - if (!symtable_visit_annotations(st, s, s->v.AsyncFunctionDef.args, - s->v.AsyncFunctionDef.returns)) - VISIT_QUIT(st, 0); - if (s->v.AsyncFunctionDef.decorator_list) - VISIT_SEQ(st, expr, s->v.AsyncFunctionDef.decorator_list); - if (!symtable_enter_block(st, s->v.AsyncFunctionDef.name, - FunctionBlock, (void *)s, - s->lineno, s->col_offset, - s->end_lineno, s->end_col_offset)) - VISIT_QUIT(st, 0); - st->st_cur->ste_coroutine = 1; - VISIT(st, arguments, s->v.AsyncFunctionDef.args); - VISIT_SEQ(st, stmt, s->v.AsyncFunctionDef.body); - if (!symtable_exit_block(st)) - VISIT_QUIT(st, 0); - break; - case AsyncWith_kind: - VISIT_SEQ(st, withitem, s->v.AsyncWith.items); - VISIT_SEQ(st, stmt, s->v.AsyncWith.body); - break; - case AsyncFor_kind: - VISIT(st, expr, s->v.AsyncFor.target); - VISIT(st, expr, s->v.AsyncFor.iter); - VISIT_SEQ(st, stmt, s->v.AsyncFor.body); - if (s->v.AsyncFor.orelse) - VISIT_SEQ(st, stmt, s->v.AsyncFor.orelse); - break; - } - VISIT_QUIT(st, 1); -} - -static int -symtable_extend_namedexpr_scope(struct symtable *st, expr_ty e) -{ - assert(st->st_stack); - assert(e->kind == Name_kind); - - PyObject *target_name = e->v.Name.id; - Py_ssize_t i, size; - struct _symtable_entry *ste; - size = PyList_GET_SIZE(st->st_stack); - assert(size); - - /* Iterate over the stack in reverse and add to the nearest adequate scope */ - for (i = size - 1; i >= 0; i--) { - ste = (struct _symtable_entry *) PyList_GET_ITEM(st->st_stack, i); - - /* If we find a comprehension scope, check for a target - * binding conflict with iteration variables, otherwise skip it - */ - if (ste->ste_comprehension) { - long target_in_scope = _PyST_GetSymbol(ste, target_name); - if (target_in_scope & DEF_COMP_ITER) { - PyErr_Format(PyExc_SyntaxError, NAMED_EXPR_COMP_CONFLICT, target_name); - PyErr_RangedSyntaxLocationObject(st->st_filename, - e->lineno, - e->col_offset + 1, - e->end_lineno, - e->end_col_offset + 1); - VISIT_QUIT(st, 0); - } - continue; - } - - /* If we find a FunctionBlock entry, add as GLOBAL/LOCAL or NONLOCAL/LOCAL */ - if (ste->ste_type == FunctionBlock) { - long target_in_scope = _PyST_GetSymbol(ste, target_name); - if (target_in_scope & DEF_GLOBAL) { - if (!symtable_add_def(st, target_name, DEF_GLOBAL, LOCATION(e))) - VISIT_QUIT(st, 0); - } else { - if (!symtable_add_def(st, target_name, DEF_NONLOCAL, LOCATION(e))) - VISIT_QUIT(st, 0); - } - if (!symtable_record_directive(st, target_name, LOCATION(e))) - VISIT_QUIT(st, 0); - - return symtable_add_def_helper(st, target_name, DEF_LOCAL, ste, LOCATION(e)); - } - /* If we find a ModuleBlock entry, add as GLOBAL */ - if (ste->ste_type == ModuleBlock) { - if (!symtable_add_def(st, target_name, DEF_GLOBAL, LOCATION(e))) - VISIT_QUIT(st, 0); - if (!symtable_record_directive(st, target_name, LOCATION(e))) - VISIT_QUIT(st, 0); - - return symtable_add_def_helper(st, target_name, DEF_GLOBAL, ste, LOCATION(e)); - } - /* Disallow usage in ClassBlock */ - if (ste->ste_type == ClassBlock) { - PyErr_Format(PyExc_SyntaxError, NAMED_EXPR_COMP_IN_CLASS); - PyErr_RangedSyntaxLocationObject(st->st_filename, - e->lineno, - e->col_offset + 1, - e->end_lineno, - e->end_col_offset + 1); - VISIT_QUIT(st, 0); - } - } - - /* We should always find either a FunctionBlock, ModuleBlock or ClassBlock - and should never fall to this case - */ - assert(0); - return 0; -} - -static int -symtable_handle_namedexpr(struct symtable *st, expr_ty e) -{ - if (st->st_cur->ste_comp_iter_expr > 0) { - /* Assignment isn't allowed in a comprehension iterable expression */ - PyErr_Format(PyExc_SyntaxError, NAMED_EXPR_COMP_ITER_EXPR); - PyErr_RangedSyntaxLocationObject(st->st_filename, - e->lineno, - e->col_offset + 1, - e->end_lineno, - e->end_col_offset + 1); - return 0; - } - if (st->st_cur->ste_comprehension) { - /* Inside a comprehension body, so find the right target scope */ - if (!symtable_extend_namedexpr_scope(st, e->v.NamedExpr.target)) - return 0; - } - VISIT(st, expr, e->v.NamedExpr.value); - VISIT(st, expr, e->v.NamedExpr.target); - return 1; -} - -static int -symtable_visit_expr(struct symtable *st, expr_ty e) -{ - if (++st->recursion_depth > st->recursion_limit) { - PyErr_SetString(PyExc_RecursionError, - "maximum recursion depth exceeded during compilation"); - VISIT_QUIT(st, 0); - } - switch (e->kind) { - case NamedExpr_kind: - if (!symtable_raise_if_annotation_block(st, "named expression", e)) { - VISIT_QUIT(st, 0); - } - if(!symtable_handle_namedexpr(st, e)) - VISIT_QUIT(st, 0); - break; - case BoolOp_kind: - VISIT_SEQ(st, expr, e->v.BoolOp.values); - break; - case BinOp_kind: - VISIT(st, expr, e->v.BinOp.left); - VISIT(st, expr, e->v.BinOp.right); - break; - case UnaryOp_kind: - VISIT(st, expr, e->v.UnaryOp.operand); - break; - case Lambda_kind: { - if (!GET_IDENTIFIER(lambda)) - VISIT_QUIT(st, 0); - if (e->v.Lambda.args->defaults) - VISIT_SEQ(st, expr, e->v.Lambda.args->defaults); - if (e->v.Lambda.args->kw_defaults) - VISIT_SEQ_WITH_NULL(st, expr, e->v.Lambda.args->kw_defaults); - if (!symtable_enter_block(st, lambda, - FunctionBlock, (void *)e, - e->lineno, e->col_offset, - e->end_lineno, e->end_col_offset)) - VISIT_QUIT(st, 0); - VISIT(st, arguments, e->v.Lambda.args); - VISIT(st, expr, e->v.Lambda.body); - if (!symtable_exit_block(st)) - VISIT_QUIT(st, 0); - break; - } - case IfExp_kind: - VISIT(st, expr, e->v.IfExp.test); - VISIT(st, expr, e->v.IfExp.body); - VISIT(st, expr, e->v.IfExp.orelse); - break; - case Dict_kind: - VISIT_SEQ_WITH_NULL(st, expr, e->v.Dict.keys); - VISIT_SEQ(st, expr, e->v.Dict.values); - break; - case Set_kind: - VISIT_SEQ(st, expr, e->v.Set.elts); - break; - case GeneratorExp_kind: - if (!symtable_visit_genexp(st, e)) - VISIT_QUIT(st, 0); - break; - case ListComp_kind: - if (!symtable_visit_listcomp(st, e)) - VISIT_QUIT(st, 0); - break; - case SetComp_kind: - if (!symtable_visit_setcomp(st, e)) - VISIT_QUIT(st, 0); - break; - case DictComp_kind: - if (!symtable_visit_dictcomp(st, e)) - VISIT_QUIT(st, 0); - break; - case Yield_kind: - if (!symtable_raise_if_annotation_block(st, "yield expression", e)) { - VISIT_QUIT(st, 0); - } - if (e->v.Yield.value) - VISIT(st, expr, e->v.Yield.value); - st->st_cur->ste_generator = 1; - if (st->st_cur->ste_comprehension) { - return symtable_raise_if_comprehension_block(st, e); - } - break; - case YieldFrom_kind: - if (!symtable_raise_if_annotation_block(st, "yield expression", e)) { - VISIT_QUIT(st, 0); - } - VISIT(st, expr, e->v.YieldFrom.value); - st->st_cur->ste_generator = 1; - if (st->st_cur->ste_comprehension) { - return symtable_raise_if_comprehension_block(st, e); - } - break; - case Await_kind: - if (!symtable_raise_if_annotation_block(st, "await expression", e)) { - VISIT_QUIT(st, 0); - } - VISIT(st, expr, e->v.Await.value); - st->st_cur->ste_coroutine = 1; - break; - case Compare_kind: - VISIT(st, expr, e->v.Compare.left); - VISIT_SEQ(st, expr, e->v.Compare.comparators); - break; - case Call_kind: - VISIT(st, expr, e->v.Call.func); - VISIT_SEQ(st, expr, e->v.Call.args); - VISIT_SEQ_WITH_NULL(st, keyword, e->v.Call.keywords); - break; - case FormattedValue_kind: - VISIT(st, expr, e->v.FormattedValue.value); - if (e->v.FormattedValue.format_spec) - VISIT(st, expr, e->v.FormattedValue.format_spec); - break; - case JoinedStr_kind: - VISIT_SEQ(st, expr, e->v.JoinedStr.values); - break; - case Constant_kind: - /* Nothing to do here. */ - break; - /* The following exprs can be assignment targets. */ - case Attribute_kind: - VISIT(st, expr, e->v.Attribute.value); - break; - case Subscript_kind: - VISIT(st, expr, e->v.Subscript.value); - VISIT(st, expr, e->v.Subscript.slice); - break; - case Starred_kind: - VISIT(st, expr, e->v.Starred.value); - break; - case Slice_kind: - if (e->v.Slice.lower) - VISIT(st, expr, e->v.Slice.lower) - if (e->v.Slice.upper) - VISIT(st, expr, e->v.Slice.upper) - if (e->v.Slice.step) - VISIT(st, expr, e->v.Slice.step) - break; - case Name_kind: - if (!symtable_add_def(st, e->v.Name.id, - e->v.Name.ctx == Load ? USE : DEF_LOCAL, LOCATION(e))) - VISIT_QUIT(st, 0); - /* Special-case super: it counts as a use of __class__ */ - if (e->v.Name.ctx == Load && - st->st_cur->ste_type == FunctionBlock && - _PyUnicode_EqualToASCIIString(e->v.Name.id, "super")) { - if (!GET_IDENTIFIER(__class__) || - !symtable_add_def(st, __class__, USE, LOCATION(e))) - VISIT_QUIT(st, 0); - } - break; - /* child nodes of List and Tuple will have expr_context set */ - case List_kind: - VISIT_SEQ(st, expr, e->v.List.elts); - break; - case Tuple_kind: - VISIT_SEQ(st, expr, e->v.Tuple.elts); - break; - } - VISIT_QUIT(st, 1); -} - -static int -symtable_visit_pattern(struct symtable *st, pattern_ty p) -{ - if (++st->recursion_depth > st->recursion_limit) { - PyErr_SetString(PyExc_RecursionError, - "maximum recursion depth exceeded during compilation"); - VISIT_QUIT(st, 0); - } - switch (p->kind) { - case MatchValue_kind: - VISIT(st, expr, p->v.MatchValue.value); - break; - case MatchSingleton_kind: - /* Nothing to do here. */ - break; - case MatchSequence_kind: - VISIT_SEQ(st, pattern, p->v.MatchSequence.patterns); - break; - case MatchStar_kind: - if (p->v.MatchStar.name) { - symtable_add_def(st, p->v.MatchStar.name, DEF_LOCAL, LOCATION(p)); - } - break; - case MatchMapping_kind: - VISIT_SEQ(st, expr, p->v.MatchMapping.keys); - VISIT_SEQ(st, pattern, p->v.MatchMapping.patterns); - if (p->v.MatchMapping.rest) { - symtable_add_def(st, p->v.MatchMapping.rest, DEF_LOCAL, LOCATION(p)); - } - break; - case MatchClass_kind: - VISIT(st, expr, p->v.MatchClass.cls); - VISIT_SEQ(st, pattern, p->v.MatchClass.patterns); - VISIT_SEQ(st, pattern, p->v.MatchClass.kwd_patterns); - break; - case MatchAs_kind: - if (p->v.MatchAs.pattern) { - VISIT(st, pattern, p->v.MatchAs.pattern); - } - if (p->v.MatchAs.name) { - symtable_add_def(st, p->v.MatchAs.name, DEF_LOCAL, LOCATION(p)); - } - break; - case MatchOr_kind: - VISIT_SEQ(st, pattern, p->v.MatchOr.patterns); - break; - } - VISIT_QUIT(st, 1); -} - -static int -symtable_implicit_arg(struct symtable *st, int pos) -{ - PyObject *id = PyUnicode_FromFormat(".%d", pos); - if (id == NULL) - return 0; - if (!symtable_add_def(st, id, DEF_PARAM, ST_LOCATION(st->st_cur))) { - Py_DECREF(id); - return 0; - } - Py_DECREF(id); - return 1; -} - -static int -symtable_visit_params(struct symtable *st, asdl_arg_seq *args) -{ - int i; - - if (!args) - return -1; - - for (i = 0; i < asdl_seq_LEN(args); i++) { - arg_ty arg = (arg_ty)asdl_seq_GET(args, i); - if (!symtable_add_def(st, arg->arg, DEF_PARAM, LOCATION(arg))) - return 0; - } - - return 1; -} - -static int -symtable_visit_annotation(struct symtable *st, expr_ty annotation) -{ - int future_annotations = st->st_future->ff_features & CO_FUTURE_ANNOTATIONS; - if (future_annotations && - !symtable_enter_block(st, GET_IDENTIFIER(_annotation), AnnotationBlock, - (void *)annotation, annotation->lineno, - annotation->col_offset, annotation->end_lineno, - annotation->end_col_offset)) { - VISIT_QUIT(st, 0); - } - VISIT(st, expr, annotation); - if (future_annotations && !symtable_exit_block(st)) { - VISIT_QUIT(st, 0); - } - return 1; -} - -static int -symtable_visit_argannotations(struct symtable *st, asdl_arg_seq *args) -{ - int i; - - if (!args) - return -1; - - for (i = 0; i < asdl_seq_LEN(args); i++) { - arg_ty arg = (arg_ty)asdl_seq_GET(args, i); - if (arg->annotation) - VISIT(st, expr, arg->annotation); - } - - return 1; -} - -static int -symtable_visit_annotations(struct symtable *st, stmt_ty o, arguments_ty a, expr_ty returns) -{ - int future_annotations = st->st_future->ff_features & CO_FUTURE_ANNOTATIONS; - if (future_annotations && - !symtable_enter_block(st, GET_IDENTIFIER(_annotation), AnnotationBlock, - (void *)o, o->lineno, o->col_offset, o->end_lineno, - o->end_col_offset)) { - VISIT_QUIT(st, 0); - } - if (a->posonlyargs && !symtable_visit_argannotations(st, a->posonlyargs)) - return 0; - if (a->args && !symtable_visit_argannotations(st, a->args)) - return 0; - if (a->vararg && a->vararg->annotation) - VISIT(st, expr, a->vararg->annotation); - if (a->kwarg && a->kwarg->annotation) - VISIT(st, expr, a->kwarg->annotation); - if (a->kwonlyargs && !symtable_visit_argannotations(st, a->kwonlyargs)) - return 0; - if (future_annotations && !symtable_exit_block(st)) { - VISIT_QUIT(st, 0); - } - if (returns && !symtable_visit_annotation(st, returns)) { - VISIT_QUIT(st, 0); - } - return 1; -} - -static int -symtable_visit_arguments(struct symtable *st, arguments_ty a) -{ - /* skip default arguments inside function block - XXX should ast be different? - */ - if (a->posonlyargs && !symtable_visit_params(st, a->posonlyargs)) - return 0; - if (a->args && !symtable_visit_params(st, a->args)) - return 0; - if (a->kwonlyargs && !symtable_visit_params(st, a->kwonlyargs)) - return 0; - if (a->vararg) { - if (!symtable_add_def(st, a->vararg->arg, DEF_PARAM, LOCATION(a->vararg))) - return 0; - st->st_cur->ste_varargs = 1; - } - if (a->kwarg) { - if (!symtable_add_def(st, a->kwarg->arg, DEF_PARAM, LOCATION(a->kwarg))) - return 0; - st->st_cur->ste_varkeywords = 1; - } - return 1; -} - - -static int -symtable_visit_excepthandler(struct symtable *st, excepthandler_ty eh) -{ - if (eh->v.ExceptHandler.type) - VISIT(st, expr, eh->v.ExceptHandler.type); - if (eh->v.ExceptHandler.name) - if (!symtable_add_def(st, eh->v.ExceptHandler.name, DEF_LOCAL, LOCATION(eh))) - return 0; - VISIT_SEQ(st, stmt, eh->v.ExceptHandler.body); - return 1; -} - -static int -symtable_visit_withitem(struct symtable *st, withitem_ty item) -{ - VISIT(st, expr, item->context_expr); - if (item->optional_vars) { - VISIT(st, expr, item->optional_vars); - } - return 1; -} - -static int -symtable_visit_match_case(struct symtable *st, match_case_ty m) -{ - VISIT(st, pattern, m->pattern); - if (m->guard) { - VISIT(st, expr, m->guard); - } - VISIT_SEQ(st, stmt, m->body); - return 1; -} - -static int -symtable_visit_alias(struct symtable *st, alias_ty a) -{ - /* Compute store_name, the name actually bound by the import - operation. It is different than a->name when a->name is a - dotted package name (e.g. spam.eggs) - */ - PyObject *store_name; - PyObject *name = (a->asname == NULL) ? a->name : a->asname; - Py_ssize_t dot = PyUnicode_FindChar(name, '.', 0, - PyUnicode_GET_LENGTH(name), 1); - if (dot != -1) { - store_name = PyUnicode_Substring(name, 0, dot); - if (!store_name) - return 0; - } - else { - store_name = name; - Py_INCREF(store_name); - } - if (!_PyUnicode_EqualToASCIIString(name, "*")) { - int r = symtable_add_def(st, store_name, DEF_IMPORT, LOCATION(a)); - Py_DECREF(store_name); - return r; - } - else { - if (st->st_cur->ste_type != ModuleBlock) { - int lineno = a->lineno; - int col_offset = a->col_offset; - int end_lineno = a->end_lineno; - int end_col_offset = a->end_col_offset; - PyErr_SetString(PyExc_SyntaxError, IMPORT_STAR_WARNING); - PyErr_RangedSyntaxLocationObject(st->st_filename, - lineno, col_offset + 1, - end_lineno, end_col_offset + 1); - Py_DECREF(store_name); - return 0; - } - Py_DECREF(store_name); - return 1; - } -} - - -static int -symtable_visit_comprehension(struct symtable *st, comprehension_ty lc) -{ - st->st_cur->ste_comp_iter_target = 1; - VISIT(st, expr, lc->target); - st->st_cur->ste_comp_iter_target = 0; - st->st_cur->ste_comp_iter_expr++; - VISIT(st, expr, lc->iter); - st->st_cur->ste_comp_iter_expr--; - VISIT_SEQ(st, expr, lc->ifs); - if (lc->is_async) { - st->st_cur->ste_coroutine = 1; - } - return 1; -} - - -static int -symtable_visit_keyword(struct symtable *st, keyword_ty k) -{ - VISIT(st, expr, k->value); - return 1; -} - - -static int -symtable_handle_comprehension(struct symtable *st, expr_ty e, - identifier scope_name, asdl_comprehension_seq *generators, - expr_ty elt, expr_ty value) -{ - int is_generator = (e->kind == GeneratorExp_kind); - comprehension_ty outermost = ((comprehension_ty) - asdl_seq_GET(generators, 0)); - /* Outermost iterator is evaluated in current scope */ - st->st_cur->ste_comp_iter_expr++; - VISIT(st, expr, outermost->iter); - st->st_cur->ste_comp_iter_expr--; - /* Create comprehension scope for the rest */ - if (!scope_name || - !symtable_enter_block(st, scope_name, FunctionBlock, (void *)e, - e->lineno, e->col_offset, - e->end_lineno, e->end_col_offset)) { - return 0; - } - switch(e->kind) { - case ListComp_kind: - st->st_cur->ste_comprehension = ListComprehension; - break; - case SetComp_kind: - st->st_cur->ste_comprehension = SetComprehension; - break; - case DictComp_kind: - st->st_cur->ste_comprehension = DictComprehension; - break; - default: - st->st_cur->ste_comprehension = GeneratorExpression; - break; - } - if (outermost->is_async) { - st->st_cur->ste_coroutine = 1; - } - - /* Outermost iter is received as an argument */ - if (!symtable_implicit_arg(st, 0)) { - symtable_exit_block(st); - return 0; - } - /* Visit iteration variable target, and mark them as such */ - st->st_cur->ste_comp_iter_target = 1; - VISIT(st, expr, outermost->target); - st->st_cur->ste_comp_iter_target = 0; - /* Visit the rest of the comprehension body */ - VISIT_SEQ(st, expr, outermost->ifs); - VISIT_SEQ_TAIL(st, comprehension, generators, 1); - if (value) - VISIT(st, expr, value); - VISIT(st, expr, elt); - st->st_cur->ste_generator = is_generator; - return symtable_exit_block(st); -} - -static int -symtable_visit_genexp(struct symtable *st, expr_ty e) -{ - return symtable_handle_comprehension(st, e, GET_IDENTIFIER(genexpr), - e->v.GeneratorExp.generators, - e->v.GeneratorExp.elt, NULL); -} - -static int -symtable_visit_listcomp(struct symtable *st, expr_ty e) -{ - return symtable_handle_comprehension(st, e, GET_IDENTIFIER(listcomp), - e->v.ListComp.generators, - e->v.ListComp.elt, NULL); -} - -static int -symtable_visit_setcomp(struct symtable *st, expr_ty e) -{ - return symtable_handle_comprehension(st, e, GET_IDENTIFIER(setcomp), - e->v.SetComp.generators, - e->v.SetComp.elt, NULL); -} - -static int -symtable_visit_dictcomp(struct symtable *st, expr_ty e) -{ - return symtable_handle_comprehension(st, e, GET_IDENTIFIER(dictcomp), - e->v.DictComp.generators, - e->v.DictComp.key, - e->v.DictComp.value); -} - -static int -symtable_raise_if_annotation_block(struct symtable *st, const char *name, expr_ty e) -{ - if (st->st_cur->ste_type != AnnotationBlock) { - return 1; - } - - PyErr_Format(PyExc_SyntaxError, ANNOTATION_NOT_ALLOWED, name); - PyErr_RangedSyntaxLocationObject(st->st_filename, - e->lineno, - e->col_offset + 1, - e->end_lineno, - e->end_col_offset + 1); - return 0; -} - -static int -symtable_raise_if_comprehension_block(struct symtable *st, expr_ty e) { - _Py_comprehension_ty type = st->st_cur->ste_comprehension; - PyErr_SetString(PyExc_SyntaxError, - (type == ListComprehension) ? "'yield' inside list comprehension" : - (type == SetComprehension) ? "'yield' inside set comprehension" : - (type == DictComprehension) ? "'yield' inside dict comprehension" : - "'yield' inside generator expression"); - PyErr_RangedSyntaxLocationObject(st->st_filename, - e->lineno, e->col_offset + 1, - e->end_lineno, e->end_col_offset + 1); - VISIT_QUIT(st, 0); -} - -struct symtable * -_Py_SymtableStringObjectFlags(const char *str, PyObject *filename, - int start, PyCompilerFlags *flags) -{ - struct symtable *st; - mod_ty mod; - PyArena *arena; - - arena = _PyArena_New(); - if (arena == NULL) - return NULL; - - mod = _PyParser_ASTFromString(str, filename, start, flags, arena); - if (mod == NULL) { - _PyArena_Free(arena); - return NULL; - } - PyFutureFeatures *future = _PyFuture_FromAST(mod, filename); - if (future == NULL) { - _PyArena_Free(arena); - return NULL; - } - future->ff_features |= flags->cf_flags; - st = _PySymtable_Build(mod, filename, future); - PyObject_Free((void *)future); - _PyArena_Free(arena); - return st; -} diff --git a/contrib/tools/python3/src/Python/sysmodule.c b/contrib/tools/python3/src/Python/sysmodule.c deleted file mode 100644 index 1a96c50d250..00000000000 --- a/contrib/tools/python3/src/Python/sysmodule.c +++ /dev/null @@ -1,3352 +0,0 @@ - -/* System module */ - -/* -Various bits of information used by the interpreter are collected in -module 'sys'. -Function member: -- exit(sts): raise SystemExit -Data members: -- stdin, stdout, stderr: standard file objects -- modules: the table of modules (dictionary) -- path: module search path (list of strings) -- argv: script arguments (list of strings) -- ps1, ps2: optional primary and secondary prompts (strings) -*/ - -#include "Python.h" -#include "pycore_ceval.h" // _Py_RecursionLimitLowerWaterMark() -#include "pycore_initconfig.h" // _PyStatus_EXCEPTION() -#include "pycore_object.h" // _PyObject_IS_GC() -#include "pycore_pathconfig.h" // _PyPathConfig_ComputeSysPath0() -#include "pycore_pyerrors.h" // _PyErr_Fetch() -#include "pycore_pylifecycle.h" // _PyErr_WriteUnraisableDefaultHook() -#include "pycore_pymem.h" // _PyMem_SetDefaultAllocator() -#include "pycore_pystate.h" // _PyThreadState_GET() -#include "pycore_tuple.h" // _PyTuple_FromArray() -#include "pycore_structseq.h" // PyStructSequence_InitType() - -#include "code.h" -#include "frameobject.h" // PyFrame_GetBack() -#include "pydtrace.h" -#include "osdefs.h" // DELIM -#include "stdlib_module_names.h" // _Py_stdlib_module_names -#include <locale.h> - -#ifdef MS_WINDOWS -#define WIN32_LEAN_AND_MEAN -#include <windows.h> -#endif /* MS_WINDOWS */ - -#ifdef MS_COREDLL -extern void *PyWin_DLLhModule; -/* A string loaded from the DLL at startup: */ -extern const char *PyWin_DLLVersionString; -#endif - -/*[clinic input] -module sys -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3726b388feee8cea]*/ - -#include "clinic/sysmodule.c.h" - -_Py_IDENTIFIER(_); -_Py_IDENTIFIER(__sizeof__); -_Py_IDENTIFIER(_xoptions); -_Py_IDENTIFIER(buffer); -_Py_IDENTIFIER(builtins); -_Py_IDENTIFIER(encoding); -_Py_IDENTIFIER(path); -_Py_IDENTIFIER(stdout); -_Py_IDENTIFIER(stderr); -_Py_IDENTIFIER(warnoptions); -_Py_IDENTIFIER(write); - -static PyObject * -sys_get_object_id(PyThreadState *tstate, _Py_Identifier *key) -{ - PyObject *sd = tstate->interp->sysdict; - if (sd == NULL) { - return NULL; - } - PyObject *exc_type, *exc_value, *exc_tb; - _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb); - PyObject *value = _PyDict_GetItemIdWithError(sd, key); - /* XXX Suppress a new exception if it was raised and restore - * the old one. */ - _PyErr_Restore(tstate, exc_type, exc_value, exc_tb); - return value; -} - -PyObject * -_PySys_GetObjectId(_Py_Identifier *key) -{ - PyThreadState *tstate = _PyThreadState_GET(); - return sys_get_object_id(tstate, key); -} - -static PyObject * -_PySys_GetObject(PyInterpreterState *interp, const char *name) -{ - PyObject *sysdict = interp->sysdict; - if (sysdict == NULL) { - return NULL; - } - return _PyDict_GetItemStringWithError(sysdict, name); -} - -PyObject * -PySys_GetObject(const char *name) -{ - PyThreadState *tstate = _PyThreadState_GET(); - - PyObject *exc_type, *exc_value, *exc_tb; - _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb); - PyObject *value = _PySys_GetObject(tstate->interp, name); - /* XXX Suppress a new exception if it was raised and restore - * the old one. */ - _PyErr_Restore(tstate, exc_type, exc_value, exc_tb); - return value; -} - -static int -sys_set_object(PyInterpreterState *interp, PyObject *key, PyObject *v) -{ - if (key == NULL) { - return -1; - } - PyObject *sd = interp->sysdict; - if (v == NULL) { - v = _PyDict_Pop(sd, key, Py_None); - if (v == NULL) { - return -1; - } - Py_DECREF(v); - return 0; - } - else { - return PyDict_SetItem(sd, key, v); - } -} - -static int -sys_set_object_id(PyInterpreterState *interp, _Py_Identifier *key, PyObject *v) -{ - return sys_set_object(interp, _PyUnicode_FromId(key), v); -} - -int -_PySys_SetObjectId(_Py_Identifier *key, PyObject *v) -{ - PyInterpreterState *interp = _PyInterpreterState_GET(); - return sys_set_object_id(interp, key, v); -} - -static int -sys_set_object_str(PyInterpreterState *interp, const char *name, PyObject *v) -{ - PyObject *key = v ? PyUnicode_InternFromString(name) - : PyUnicode_FromString(name); - int r = sys_set_object(interp, key, v); - Py_XDECREF(key); - return r; -} - -int -PySys_SetObject(const char *name, PyObject *v) -{ - PyInterpreterState *interp = _PyInterpreterState_GET(); - return sys_set_object_str(interp, name, v); -} - - -static int -should_audit(PyInterpreterState *interp) -{ - /* interp must not be NULL, but test it just in case for extra safety */ - assert(interp != NULL); - if (!interp) { - return 0; - } - return (interp->runtime->audit_hook_head - || interp->audit_hooks - || PyDTrace_AUDIT_ENABLED()); -} - - -static int -sys_audit_tstate(PyThreadState *ts, const char *event, - const char *argFormat, va_list vargs) -{ - /* N format is inappropriate, because you do not know - whether the reference is consumed by the call. - Assert rather than exception for perf reasons */ - assert(!argFormat || !strchr(argFormat, 'N')); - - if (!ts) { - /* Audit hooks cannot be called with a NULL thread state */ - return 0; - } - - /* The current implementation cannot be called if tstate is not - the current Python thread state. */ - assert(ts == _PyThreadState_GET()); - - /* Early exit when no hooks are registered */ - PyInterpreterState *is = ts->interp; - if (!should_audit(is)) { - return 0; - } - - PyObject *eventName = NULL; - PyObject *eventArgs = NULL; - PyObject *hooks = NULL; - PyObject *hook = NULL; - int res = -1; - - int dtrace = PyDTrace_AUDIT_ENABLED(); - - PyObject *exc_type, *exc_value, *exc_tb; - _PyErr_Fetch(ts, &exc_type, &exc_value, &exc_tb); - - /* Initialize event args now */ - if (argFormat && argFormat[0]) { - eventArgs = _Py_VaBuildValue_SizeT(argFormat, vargs); - if (eventArgs && !PyTuple_Check(eventArgs)) { - PyObject *argTuple = PyTuple_Pack(1, eventArgs); - Py_DECREF(eventArgs); - eventArgs = argTuple; - } - } - else { - eventArgs = PyTuple_New(0); - } - if (!eventArgs) { - goto exit; - } - - /* Call global hooks */ - _Py_AuditHookEntry *e = is->runtime->audit_hook_head; - for (; e; e = e->next) { - if (e->hookCFunction(event, eventArgs, e->userData) < 0) { - goto exit; - } - } - - /* Dtrace USDT point */ - if (dtrace) { - PyDTrace_AUDIT(event, (void *)eventArgs); - } - - /* Call interpreter hooks */ - if (is->audit_hooks) { - eventName = PyUnicode_FromString(event); - if (!eventName) { - goto exit; - } - - hooks = PyObject_GetIter(is->audit_hooks); - if (!hooks) { - goto exit; - } - - /* Disallow tracing in hooks unless explicitly enabled */ - ts->tracing++; - ts->cframe->use_tracing = 0; - while ((hook = PyIter_Next(hooks)) != NULL) { - _Py_IDENTIFIER(__cantrace__); - PyObject *o; - int canTrace = _PyObject_LookupAttrId(hook, &PyId___cantrace__, &o); - if (o) { - canTrace = PyObject_IsTrue(o); - Py_DECREF(o); - } - if (canTrace < 0) { - break; - } - if (canTrace) { - ts->cframe->use_tracing = (ts->c_tracefunc || ts->c_profilefunc); - ts->tracing--; - } - PyObject* args[2] = {eventName, eventArgs}; - o = _PyObject_FastCallTstate(ts, hook, args, 2); - if (canTrace) { - ts->tracing++; - ts->cframe->use_tracing = 0; - } - if (!o) { - break; - } - Py_DECREF(o); - Py_CLEAR(hook); - } - ts->cframe->use_tracing = (ts->c_tracefunc || ts->c_profilefunc); - ts->tracing--; - if (_PyErr_Occurred(ts)) { - goto exit; - } - } - - res = 0; - -exit: - Py_XDECREF(hook); - Py_XDECREF(hooks); - Py_XDECREF(eventName); - Py_XDECREF(eventArgs); - - if (!res) { - _PyErr_Restore(ts, exc_type, exc_value, exc_tb); - } - else { - assert(_PyErr_Occurred(ts)); - Py_XDECREF(exc_type); - Py_XDECREF(exc_value); - Py_XDECREF(exc_tb); - } - - return res; -} - -int -_PySys_Audit(PyThreadState *tstate, const char *event, - const char *argFormat, ...) -{ - va_list vargs; -#ifdef HAVE_STDARG_PROTOTYPES - va_start(vargs, argFormat); -#else - va_start(vargs); -#endif - int res = sys_audit_tstate(tstate, event, argFormat, vargs); - va_end(vargs); - return res; -} - -int -PySys_Audit(const char *event, const char *argFormat, ...) -{ - PyThreadState *tstate = _PyThreadState_GET(); - va_list vargs; -#ifdef HAVE_STDARG_PROTOTYPES - va_start(vargs, argFormat); -#else - va_start(vargs); -#endif - int res = sys_audit_tstate(tstate, event, argFormat, vargs); - va_end(vargs); - return res; -} - -/* We expose this function primarily for our own cleanup during - * finalization. In general, it should not need to be called, - * and as such the function is not exported. - * - * Must be finalizing to clear hooks */ -void -_PySys_ClearAuditHooks(PyThreadState *ts) -{ - assert(ts != NULL); - if (!ts) { - return; - } - - _PyRuntimeState *runtime = ts->interp->runtime; - PyThreadState *finalizing = _PyRuntimeState_GetFinalizing(runtime); - assert(finalizing == ts); - if (finalizing != ts) { - return; - } - - const PyConfig *config = _PyInterpreterState_GetConfig(ts->interp); - if (config->verbose) { - PySys_WriteStderr("# clear sys.audit hooks\n"); - } - - /* Hooks can abort later hooks for this event, but cannot - abort the clear operation itself. */ - _PySys_Audit(ts, "cpython._PySys_ClearAuditHooks", NULL); - _PyErr_Clear(ts); - - _Py_AuditHookEntry *e = runtime->audit_hook_head, *n; - runtime->audit_hook_head = NULL; - while (e) { - n = e->next; - PyMem_RawFree(e); - e = n; - } -} - -int -PySys_AddAuditHook(Py_AuditHookFunction hook, void *userData) -{ - /* tstate can be NULL, so access directly _PyRuntime: - PySys_AddAuditHook() can be called before Python is initialized. */ - _PyRuntimeState *runtime = &_PyRuntime; - PyThreadState *tstate; - if (runtime->initialized) { - tstate = _PyRuntimeState_GetThreadState(runtime); - } - else { - tstate = NULL; - } - - /* Invoke existing audit hooks to allow them an opportunity to abort. */ - /* Cannot invoke hooks until we are initialized */ - if (tstate != NULL) { - if (_PySys_Audit(tstate, "sys.addaudithook", NULL) < 0) { - if (_PyErr_ExceptionMatches(tstate, PyExc_RuntimeError)) { - /* We do not report errors derived from RuntimeError */ - _PyErr_Clear(tstate); - return 0; - } - return -1; - } - } - - _Py_AuditHookEntry *e = runtime->audit_hook_head; - if (!e) { - e = (_Py_AuditHookEntry*)PyMem_RawMalloc(sizeof(_Py_AuditHookEntry)); - runtime->audit_hook_head = e; - } else { - while (e->next) { - e = e->next; - } - e = e->next = (_Py_AuditHookEntry*)PyMem_RawMalloc( - sizeof(_Py_AuditHookEntry)); - } - - if (!e) { - if (tstate != NULL) { - _PyErr_NoMemory(tstate); - } - return -1; - } - - e->next = NULL; - e->hookCFunction = (Py_AuditHookFunction)hook; - e->userData = userData; - - return 0; -} - -/*[clinic input] -sys.addaudithook - - hook: object - -Adds a new audit hook callback. -[clinic start generated code]*/ - -static PyObject * -sys_addaudithook_impl(PyObject *module, PyObject *hook) -/*[clinic end generated code: output=4f9c17aaeb02f44e input=0f3e191217a45e34]*/ -{ - PyThreadState *tstate = _PyThreadState_GET(); - - /* Invoke existing audit hooks to allow them an opportunity to abort. */ - if (_PySys_Audit(tstate, "sys.addaudithook", NULL) < 0) { - if (_PyErr_ExceptionMatches(tstate, PyExc_Exception)) { - /* We do not report errors derived from Exception */ - _PyErr_Clear(tstate); - Py_RETURN_NONE; - } - return NULL; - } - - PyInterpreterState *interp = tstate->interp; - if (interp->audit_hooks == NULL) { - interp->audit_hooks = PyList_New(0); - if (interp->audit_hooks == NULL) { - return NULL; - } - } - - if (PyList_Append(interp->audit_hooks, hook) < 0) { - return NULL; - } - - Py_RETURN_NONE; -} - -PyDoc_STRVAR(audit_doc, -"audit(event, *args)\n\ -\n\ -Passes the event to any audit hooks that are attached."); - -static PyObject * -sys_audit(PyObject *self, PyObject *const *args, Py_ssize_t argc) -{ - PyThreadState *tstate = _PyThreadState_GET(); - _Py_EnsureTstateNotNULL(tstate); - - if (argc == 0) { - _PyErr_SetString(tstate, PyExc_TypeError, - "audit() missing 1 required positional argument: " - "'event'"); - return NULL; - } - - if (!should_audit(tstate->interp)) { - Py_RETURN_NONE; - } - - PyObject *auditEvent = args[0]; - if (!auditEvent) { - _PyErr_SetString(tstate, PyExc_TypeError, - "expected str for argument 'event'"); - return NULL; - } - if (!PyUnicode_Check(auditEvent)) { - _PyErr_Format(tstate, PyExc_TypeError, - "expected str for argument 'event', not %.200s", - Py_TYPE(auditEvent)->tp_name); - return NULL; - } - const char *event = PyUnicode_AsUTF8(auditEvent); - if (!event) { - return NULL; - } - - PyObject *auditArgs = _PyTuple_FromArray(args + 1, argc - 1); - if (!auditArgs) { - return NULL; - } - - int res = _PySys_Audit(tstate, event, "O", auditArgs); - Py_DECREF(auditArgs); - - if (res < 0) { - return NULL; - } - - Py_RETURN_NONE; -} - - -static PyObject * -sys_breakpointhook(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *keywords) -{ - PyThreadState *tstate = _PyThreadState_GET(); - assert(!_PyErr_Occurred(tstate)); - char *envar = Py_GETENV("PYTHONBREAKPOINT"); - - if (envar == NULL || strlen(envar) == 0) { - envar = "pdb.set_trace"; - } - else if (!strcmp(envar, "0")) { - /* The breakpoint is explicitly no-op'd. */ - Py_RETURN_NONE; - } - /* According to POSIX the string returned by getenv() might be invalidated - * or the string content might be overwritten by a subsequent call to - * getenv(). Since importing a module can performs the getenv() calls, - * we need to save a copy of envar. */ - envar = _PyMem_RawStrdup(envar); - if (envar == NULL) { - _PyErr_NoMemory(tstate); - return NULL; - } - const char *last_dot = strrchr(envar, '.'); - const char *attrname = NULL; - PyObject *modulepath = NULL; - - if (last_dot == NULL) { - /* The breakpoint is a built-in, e.g. PYTHONBREAKPOINT=int */ - modulepath = PyUnicode_FromString("builtins"); - attrname = envar; - } - else if (last_dot != envar) { - /* Split on the last dot; */ - modulepath = PyUnicode_FromStringAndSize(envar, last_dot - envar); - attrname = last_dot + 1; - } - else { - goto warn; - } - if (modulepath == NULL) { - PyMem_RawFree(envar); - return NULL; - } - - PyObject *module = PyImport_Import(modulepath); - Py_DECREF(modulepath); - - if (module == NULL) { - if (_PyErr_ExceptionMatches(tstate, PyExc_ImportError)) { - goto warn; - } - PyMem_RawFree(envar); - return NULL; - } - - PyObject *hook = PyObject_GetAttrString(module, attrname); - Py_DECREF(module); - - if (hook == NULL) { - if (_PyErr_ExceptionMatches(tstate, PyExc_AttributeError)) { - goto warn; - } - PyMem_RawFree(envar); - return NULL; - } - PyMem_RawFree(envar); - PyObject *retval = PyObject_Vectorcall(hook, args, nargs, keywords); - Py_DECREF(hook); - return retval; - - warn: - /* If any of the imports went wrong, then warn and ignore. */ - _PyErr_Clear(tstate); - int status = PyErr_WarnFormat( - PyExc_RuntimeWarning, 0, - "Ignoring unimportable $PYTHONBREAKPOINT: \"%s\"", envar); - PyMem_RawFree(envar); - if (status < 0) { - /* Printing the warning raised an exception. */ - return NULL; - } - /* The warning was (probably) issued. */ - Py_RETURN_NONE; -} - -PyDoc_STRVAR(breakpointhook_doc, -"breakpointhook(*args, **kws)\n" -"\n" -"This hook function is called by built-in breakpoint().\n" -); - -/* Write repr(o) to sys.stdout using sys.stdout.encoding and 'backslashreplace' - error handler. If sys.stdout has a buffer attribute, use - sys.stdout.buffer.write(encoded), otherwise redecode the string and use - sys.stdout.write(redecoded). - - Helper function for sys_displayhook(). */ -static int -sys_displayhook_unencodable(PyObject *outf, PyObject *o) -{ - PyObject *stdout_encoding = NULL; - PyObject *encoded, *escaped_str, *repr_str, *buffer, *result; - const char *stdout_encoding_str; - int ret; - - stdout_encoding = _PyObject_GetAttrId(outf, &PyId_encoding); - if (stdout_encoding == NULL) - goto error; - stdout_encoding_str = PyUnicode_AsUTF8(stdout_encoding); - if (stdout_encoding_str == NULL) - goto error; - - repr_str = PyObject_Repr(o); - if (repr_str == NULL) - goto error; - encoded = PyUnicode_AsEncodedString(repr_str, - stdout_encoding_str, - "backslashreplace"); - Py_DECREF(repr_str); - if (encoded == NULL) - goto error; - - if (_PyObject_LookupAttrId(outf, &PyId_buffer, &buffer) < 0) { - Py_DECREF(encoded); - goto error; - } - if (buffer) { - result = _PyObject_CallMethodIdOneArg(buffer, &PyId_write, encoded); - Py_DECREF(buffer); - Py_DECREF(encoded); - if (result == NULL) - goto error; - Py_DECREF(result); - } - else { - escaped_str = PyUnicode_FromEncodedObject(encoded, - stdout_encoding_str, - "strict"); - Py_DECREF(encoded); - if (PyFile_WriteObject(escaped_str, outf, Py_PRINT_RAW) != 0) { - Py_DECREF(escaped_str); - goto error; - } - Py_DECREF(escaped_str); - } - ret = 0; - goto finally; - -error: - ret = -1; -finally: - Py_XDECREF(stdout_encoding); - return ret; -} - -/*[clinic input] -sys.displayhook - - object as o: object - / - -Print an object to sys.stdout and also save it in builtins._ -[clinic start generated code]*/ - -static PyObject * -sys_displayhook(PyObject *module, PyObject *o) -/*[clinic end generated code: output=347477d006df92ed input=08ba730166d7ef72]*/ -{ - PyObject *outf; - PyObject *builtins; - static PyObject *newline = NULL; - PyThreadState *tstate = _PyThreadState_GET(); - - builtins = _PyImport_GetModuleId(&PyId_builtins); - if (builtins == NULL) { - if (!_PyErr_Occurred(tstate)) { - _PyErr_SetString(tstate, PyExc_RuntimeError, - "lost builtins module"); - } - return NULL; - } - Py_DECREF(builtins); - - /* Print value except if None */ - /* After printing, also assign to '_' */ - /* Before, set '_' to None to avoid recursion */ - if (o == Py_None) { - Py_RETURN_NONE; - } - if (_PyObject_SetAttrId(builtins, &PyId__, Py_None) != 0) - return NULL; - outf = sys_get_object_id(tstate, &PyId_stdout); - if (outf == NULL || outf == Py_None) { - _PyErr_SetString(tstate, PyExc_RuntimeError, "lost sys.stdout"); - return NULL; - } - if (PyFile_WriteObject(o, outf, 0) != 0) { - if (_PyErr_ExceptionMatches(tstate, PyExc_UnicodeEncodeError)) { - int err; - /* repr(o) is not encodable to sys.stdout.encoding with - * sys.stdout.errors error handler (which is probably 'strict') */ - _PyErr_Clear(tstate); - err = sys_displayhook_unencodable(outf, o); - if (err) { - return NULL; - } - } - else { - return NULL; - } - } - if (newline == NULL) { - newline = PyUnicode_FromString("\n"); - if (newline == NULL) - return NULL; - } - if (PyFile_WriteObject(newline, outf, Py_PRINT_RAW) != 0) - return NULL; - if (_PyObject_SetAttrId(builtins, &PyId__, o) != 0) - return NULL; - Py_RETURN_NONE; -} - - -/*[clinic input] -sys.excepthook - - exctype: object - value: object - traceback: object - / - -Handle an exception by displaying it with a traceback on sys.stderr. -[clinic start generated code]*/ - -static PyObject * -sys_excepthook_impl(PyObject *module, PyObject *exctype, PyObject *value, - PyObject *traceback) -/*[clinic end generated code: output=18d99fdda21b6b5e input=ecf606fa826f19d9]*/ -{ - PyErr_Display(exctype, value, traceback); - Py_RETURN_NONE; -} - - -/*[clinic input] -sys.exc_info - -Return current exception information: (type, value, traceback). - -Return information about the most recent exception caught by an except -clause in the current stack frame or in an older stack frame. -[clinic start generated code]*/ - -static PyObject * -sys_exc_info_impl(PyObject *module) -/*[clinic end generated code: output=3afd0940cf3a4d30 input=b5c5bf077788a3e5]*/ -{ - _PyErr_StackItem *err_info = _PyErr_GetTopmostException(_PyThreadState_GET()); - return Py_BuildValue( - "(OOO)", - err_info->exc_type != NULL ? err_info->exc_type : Py_None, - err_info->exc_value != NULL ? err_info->exc_value : Py_None, - err_info->exc_traceback != NULL ? - err_info->exc_traceback : Py_None); -} - - -/*[clinic input] -sys.unraisablehook - - unraisable: object - / - -Handle an unraisable exception. - -The unraisable argument has the following attributes: - -* exc_type: Exception type. -* exc_value: Exception value, can be None. -* exc_traceback: Exception traceback, can be None. -* err_msg: Error message, can be None. -* object: Object causing the exception, can be None. -[clinic start generated code]*/ - -static PyObject * -sys_unraisablehook(PyObject *module, PyObject *unraisable) -/*[clinic end generated code: output=bb92838b32abaa14 input=ec3af148294af8d3]*/ -{ - return _PyErr_WriteUnraisableDefaultHook(unraisable); -} - - -/*[clinic input] -sys.exit - - status: object = None - / - -Exit the interpreter by raising SystemExit(status). - -If the status is omitted or None, it defaults to zero (i.e., success). -If the status is an integer, it will be used as the system exit status. -If it is another kind of object, it will be printed and the system -exit status will be one (i.e., failure). -[clinic start generated code]*/ - -static PyObject * -sys_exit_impl(PyObject *module, PyObject *status) -/*[clinic end generated code: output=13870986c1ab2ec0 input=b86ca9497baa94f2]*/ -{ - /* Raise SystemExit so callers may catch it or clean up. */ - PyErr_SetObject(PyExc_SystemExit, status); - return NULL; -} - - - -/*[clinic input] -sys.getdefaultencoding - -Return the current default encoding used by the Unicode implementation. -[clinic start generated code]*/ - -static PyObject * -sys_getdefaultencoding_impl(PyObject *module) -/*[clinic end generated code: output=256d19dfcc0711e6 input=d416856ddbef6909]*/ -{ - return PyUnicode_FromString(PyUnicode_GetDefaultEncoding()); -} - -/*[clinic input] -sys.getfilesystemencoding - -Return the encoding used to convert Unicode filenames to OS filenames. -[clinic start generated code]*/ - -static PyObject * -sys_getfilesystemencoding_impl(PyObject *module) -/*[clinic end generated code: output=1dc4bdbe9be44aa7 input=8475f8649b8c7d8c]*/ -{ - PyInterpreterState *interp = _PyInterpreterState_GET(); - const PyConfig *config = _PyInterpreterState_GetConfig(interp); - return PyUnicode_FromWideChar(config->filesystem_encoding, -1); -} - -/*[clinic input] -sys.getfilesystemencodeerrors - -Return the error mode used Unicode to OS filename conversion. -[clinic start generated code]*/ - -static PyObject * -sys_getfilesystemencodeerrors_impl(PyObject *module) -/*[clinic end generated code: output=ba77b36bbf7c96f5 input=22a1e8365566f1e5]*/ -{ - PyInterpreterState *interp = _PyInterpreterState_GET(); - const PyConfig *config = _PyInterpreterState_GetConfig(interp); - return PyUnicode_FromWideChar(config->filesystem_errors, -1); -} - -/*[clinic input] -sys.intern - - string as s: unicode - / - -``Intern'' the given string. - -This enters the string in the (global) table of interned strings whose -purpose is to speed up dictionary lookups. Return the string itself or -the previously interned string object with the same value. -[clinic start generated code]*/ - -static PyObject * -sys_intern_impl(PyObject *module, PyObject *s) -/*[clinic end generated code: output=be680c24f5c9e5d6 input=849483c006924e2f]*/ -{ - if (PyUnicode_CheckExact(s)) { - Py_INCREF(s); - PyUnicode_InternInPlace(&s); - return s; - } - else { - PyErr_Format(PyExc_TypeError, - "can't intern %.400s", Py_TYPE(s)->tp_name); - return NULL; - } -} - - -/* - * Cached interned string objects used for calling the profile and - * trace functions. Initialized by trace_init(). - */ -static PyObject *whatstrings[8] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; - -static int -trace_init(void) -{ - static const char * const whatnames[8] = { - "call", "exception", "line", "return", - "c_call", "c_exception", "c_return", - "opcode" - }; - PyObject *name; - int i; - for (i = 0; i < 8; ++i) { - if (whatstrings[i] == NULL) { - name = PyUnicode_InternFromString(whatnames[i]); - if (name == NULL) - return -1; - whatstrings[i] = name; - } - } - return 0; -} - - -static PyObject * -call_trampoline(PyThreadState *tstate, PyObject* callback, - PyFrameObject *frame, int what, PyObject *arg) -{ - if (PyFrame_FastToLocalsWithError(frame) < 0) { - return NULL; - } - - PyObject *stack[3]; - stack[0] = (PyObject *)frame; - stack[1] = whatstrings[what]; - stack[2] = (arg != NULL) ? arg : Py_None; - - /* call the Python-level function */ - PyObject *result = _PyObject_FastCallTstate(tstate, callback, stack, 3); - - PyFrame_LocalsToFast(frame, 1); - if (result == NULL) { - PyTraceBack_Here(frame); - } - - return result; -} - -static int -profile_trampoline(PyObject *self, PyFrameObject *frame, - int what, PyObject *arg) -{ - if (arg == NULL) { - arg = Py_None; - } - - PyThreadState *tstate = _PyThreadState_GET(); - PyObject *result = call_trampoline(tstate, self, frame, what, arg); - if (result == NULL) { - _PyEval_SetProfile(tstate, NULL, NULL); - return -1; - } - - Py_DECREF(result); - return 0; -} - -static int -trace_trampoline(PyObject *self, PyFrameObject *frame, - int what, PyObject *arg) -{ - PyObject *callback; - if (what == PyTrace_CALL) { - callback = self; - } - else { - callback = frame->f_trace; - } - if (callback == NULL) { - return 0; - } - - PyThreadState *tstate = _PyThreadState_GET(); - PyObject *result = call_trampoline(tstate, callback, frame, what, arg); - if (result == NULL) { - _PyEval_SetTrace(tstate, NULL, NULL); - Py_CLEAR(frame->f_trace); - return -1; - } - - if (result != Py_None) { - Py_XSETREF(frame->f_trace, result); - } - else { - Py_DECREF(result); - } - return 0; -} - -static PyObject * -sys_settrace(PyObject *self, PyObject *args) -{ - if (trace_init() == -1) { - return NULL; - } - - PyThreadState *tstate = _PyThreadState_GET(); - if (args == Py_None) { - if (_PyEval_SetTrace(tstate, NULL, NULL) < 0) { - return NULL; - } - } - else { - if (_PyEval_SetTrace(tstate, trace_trampoline, args) < 0) { - return NULL; - } - } - Py_RETURN_NONE; -} - -PyDoc_STRVAR(settrace_doc, -"settrace(function)\n\ -\n\ -Set the global debug tracing function. It will be called on each\n\ -function call. See the debugger chapter in the library manual." -); - -/*[clinic input] -sys.gettrace - -Return the global debug tracing function set with sys.settrace. - -See the debugger chapter in the library manual. -[clinic start generated code]*/ - -static PyObject * -sys_gettrace_impl(PyObject *module) -/*[clinic end generated code: output=e97e3a4d8c971b6e input=373b51bb2147f4d8]*/ -{ - PyThreadState *tstate = _PyThreadState_GET(); - PyObject *temp = tstate->c_traceobj; - - if (temp == NULL) - temp = Py_None; - Py_INCREF(temp); - return temp; -} - -static PyObject * -sys_setprofile(PyObject *self, PyObject *args) -{ - if (trace_init() == -1) { - return NULL; - } - - PyThreadState *tstate = _PyThreadState_GET(); - if (args == Py_None) { - if (_PyEval_SetProfile(tstate, NULL, NULL) < 0) { - return NULL; - } - } - else { - if (_PyEval_SetProfile(tstate, profile_trampoline, args) < 0) { - return NULL; - } - } - Py_RETURN_NONE; -} - -PyDoc_STRVAR(setprofile_doc, -"setprofile(function)\n\ -\n\ -Set the profiling function. It will be called on each function call\n\ -and return. See the profiler chapter in the library manual." -); - -/*[clinic input] -sys.getprofile - -Return the profiling function set with sys.setprofile. - -See the profiler chapter in the library manual. -[clinic start generated code]*/ - -static PyObject * -sys_getprofile_impl(PyObject *module) -/*[clinic end generated code: output=579b96b373448188 input=1b3209d89a32965d]*/ -{ - PyThreadState *tstate = _PyThreadState_GET(); - PyObject *temp = tstate->c_profileobj; - - if (temp == NULL) - temp = Py_None; - Py_INCREF(temp); - return temp; -} - - -/*[clinic input] -sys.setswitchinterval - - interval: double - / - -Set the ideal thread switching delay inside the Python interpreter. - -The actual frequency of switching threads can be lower if the -interpreter executes long sequences of uninterruptible code -(this is implementation-specific and workload-dependent). - -The parameter must represent the desired switching delay in seconds -A typical value is 0.005 (5 milliseconds). -[clinic start generated code]*/ - -static PyObject * -sys_setswitchinterval_impl(PyObject *module, double interval) -/*[clinic end generated code: output=65a19629e5153983 input=561b477134df91d9]*/ -{ - if (interval <= 0.0) { - PyErr_SetString(PyExc_ValueError, - "switch interval must be strictly positive"); - return NULL; - } - _PyEval_SetSwitchInterval((unsigned long) (1e6 * interval)); - Py_RETURN_NONE; -} - - -/*[clinic input] -sys.getswitchinterval -> double - -Return the current thread switch interval; see sys.setswitchinterval(). -[clinic start generated code]*/ - -static double -sys_getswitchinterval_impl(PyObject *module) -/*[clinic end generated code: output=a38c277c85b5096d input=bdf9d39c0ebbbb6f]*/ -{ - return 1e-6 * _PyEval_GetSwitchInterval(); -} - -/*[clinic input] -sys.setrecursionlimit - - limit as new_limit: int - / - -Set the maximum depth of the Python interpreter stack to n. - -This limit prevents infinite recursion from causing an overflow of the C -stack and crashing Python. The highest possible limit is platform- -dependent. -[clinic start generated code]*/ - -static PyObject * -sys_setrecursionlimit_impl(PyObject *module, int new_limit) -/*[clinic end generated code: output=35e1c64754800ace input=b0f7a23393924af3]*/ -{ - PyThreadState *tstate = _PyThreadState_GET(); - - if (new_limit < 1) { - _PyErr_SetString(tstate, PyExc_ValueError, - "recursion limit must be greater or equal than 1"); - return NULL; - } - - /* Issue #25274: When the recursion depth hits the recursion limit in - _Py_CheckRecursiveCall(), the overflowed flag of the thread state is - set to 1 and a RecursionError is raised. The overflowed flag is reset - to 0 when the recursion depth goes below the low-water mark: see - Py_LeaveRecursiveCall(). - - Reject too low new limit if the current recursion depth is higher than - the new low-water mark. Otherwise it may not be possible anymore to - reset the overflowed flag to 0. */ - if (tstate->recursion_depth >= new_limit) { - _PyErr_Format(tstate, PyExc_RecursionError, - "cannot set the recursion limit to %i at " - "the recursion depth %i: the limit is too low", - new_limit, tstate->recursion_depth); - return NULL; - } - - Py_SetRecursionLimit(new_limit); - Py_RETURN_NONE; -} - -/*[clinic input] -sys.set_coroutine_origin_tracking_depth - - depth: int - -Enable or disable origin tracking for coroutine objects in this thread. - -Coroutine objects will track 'depth' frames of traceback information -about where they came from, available in their cr_origin attribute. - -Set a depth of 0 to disable. -[clinic start generated code]*/ - -static PyObject * -sys_set_coroutine_origin_tracking_depth_impl(PyObject *module, int depth) -/*[clinic end generated code: output=0a2123c1cc6759c5 input=a1d0a05f89d2c426]*/ -{ - PyThreadState *tstate = _PyThreadState_GET(); - if (depth < 0) { - _PyErr_SetString(tstate, PyExc_ValueError, "depth must be >= 0"); - return NULL; - } - _PyEval_SetCoroutineOriginTrackingDepth(tstate, depth); - Py_RETURN_NONE; -} - -/*[clinic input] -sys.get_coroutine_origin_tracking_depth -> int - -Check status of origin tracking for coroutine objects in this thread. -[clinic start generated code]*/ - -static int -sys_get_coroutine_origin_tracking_depth_impl(PyObject *module) -/*[clinic end generated code: output=3699f7be95a3afb8 input=335266a71205b61a]*/ -{ - return _PyEval_GetCoroutineOriginTrackingDepth(); -} - -static PyTypeObject AsyncGenHooksType; - -PyDoc_STRVAR(asyncgen_hooks_doc, -"asyncgen_hooks\n\ -\n\ -A named tuple providing information about asynchronous\n\ -generators hooks. The attributes are read only."); - -static PyStructSequence_Field asyncgen_hooks_fields[] = { - {"firstiter", "Hook to intercept first iteration"}, - {"finalizer", "Hook to intercept finalization"}, - {0} -}; - -static PyStructSequence_Desc asyncgen_hooks_desc = { - "asyncgen_hooks", /* name */ - asyncgen_hooks_doc, /* doc */ - asyncgen_hooks_fields , /* fields */ - 2 -}; - -static PyObject * -sys_set_asyncgen_hooks(PyObject *self, PyObject *args, PyObject *kw) -{ - static char *keywords[] = {"firstiter", "finalizer", NULL}; - PyObject *firstiter = NULL; - PyObject *finalizer = NULL; - - if (!PyArg_ParseTupleAndKeywords( - args, kw, "|OO", keywords, - &firstiter, &finalizer)) { - return NULL; - } - - if (finalizer && finalizer != Py_None) { - if (!PyCallable_Check(finalizer)) { - PyErr_Format(PyExc_TypeError, - "callable finalizer expected, got %.50s", - Py_TYPE(finalizer)->tp_name); - return NULL; - } - if (_PyEval_SetAsyncGenFinalizer(finalizer) < 0) { - return NULL; - } - } - else if (finalizer == Py_None && _PyEval_SetAsyncGenFinalizer(NULL) < 0) { - return NULL; - } - - if (firstiter && firstiter != Py_None) { - if (!PyCallable_Check(firstiter)) { - PyErr_Format(PyExc_TypeError, - "callable firstiter expected, got %.50s", - Py_TYPE(firstiter)->tp_name); - return NULL; - } - if (_PyEval_SetAsyncGenFirstiter(firstiter) < 0) { - return NULL; - } - } - else if (firstiter == Py_None && _PyEval_SetAsyncGenFirstiter(NULL) < 0) { - return NULL; - } - - Py_RETURN_NONE; -} - -PyDoc_STRVAR(set_asyncgen_hooks_doc, -"set_asyncgen_hooks(* [, firstiter] [, finalizer])\n\ -\n\ -Set a finalizer for async generators objects." -); - -/*[clinic input] -sys.get_asyncgen_hooks - -Return the installed asynchronous generators hooks. - -This returns a namedtuple of the form (firstiter, finalizer). -[clinic start generated code]*/ - -static PyObject * -sys_get_asyncgen_hooks_impl(PyObject *module) -/*[clinic end generated code: output=53a253707146f6cf input=3676b9ea62b14625]*/ -{ - PyObject *res; - PyObject *firstiter = _PyEval_GetAsyncGenFirstiter(); - PyObject *finalizer = _PyEval_GetAsyncGenFinalizer(); - - res = PyStructSequence_New(&AsyncGenHooksType); - if (res == NULL) { - return NULL; - } - - if (firstiter == NULL) { - firstiter = Py_None; - } - - if (finalizer == NULL) { - finalizer = Py_None; - } - - Py_INCREF(firstiter); - PyStructSequence_SET_ITEM(res, 0, firstiter); - - Py_INCREF(finalizer); - PyStructSequence_SET_ITEM(res, 1, finalizer); - - return res; -} - - -static PyTypeObject Hash_InfoType; - -PyDoc_STRVAR(hash_info_doc, -"hash_info\n\ -\n\ -A named tuple providing parameters used for computing\n\ -hashes. The attributes are read only."); - -static PyStructSequence_Field hash_info_fields[] = { - {"width", "width of the type used for hashing, in bits"}, - {"modulus", "prime number giving the modulus on which the hash " - "function is based"}, - {"inf", "value to be used for hash of a positive infinity"}, - {"nan", "value to be used for hash of a nan"}, - {"imag", "multiplier used for the imaginary part of a complex number"}, - {"algorithm", "name of the algorithm for hashing of str, bytes and " - "memoryviews"}, - {"hash_bits", "internal output size of hash algorithm"}, - {"seed_bits", "seed size of hash algorithm"}, - {"cutoff", "small string optimization cutoff"}, - {NULL, NULL} -}; - -static PyStructSequence_Desc hash_info_desc = { - "sys.hash_info", - hash_info_doc, - hash_info_fields, - 9, -}; - -static PyObject * -get_hash_info(PyThreadState *tstate) -{ - PyObject *hash_info; - int field = 0; - PyHash_FuncDef *hashfunc; - hash_info = PyStructSequence_New(&Hash_InfoType); - if (hash_info == NULL) - return NULL; - hashfunc = PyHash_GetFuncDef(); - PyStructSequence_SET_ITEM(hash_info, field++, - PyLong_FromLong(8*sizeof(Py_hash_t))); - PyStructSequence_SET_ITEM(hash_info, field++, - PyLong_FromSsize_t(_PyHASH_MODULUS)); - PyStructSequence_SET_ITEM(hash_info, field++, - PyLong_FromLong(_PyHASH_INF)); - PyStructSequence_SET_ITEM(hash_info, field++, - PyLong_FromLong(0)); // This is no longer used - PyStructSequence_SET_ITEM(hash_info, field++, - PyLong_FromLong(_PyHASH_IMAG)); - PyStructSequence_SET_ITEM(hash_info, field++, - PyUnicode_FromString(hashfunc->name)); - PyStructSequence_SET_ITEM(hash_info, field++, - PyLong_FromLong(hashfunc->hash_bits)); - PyStructSequence_SET_ITEM(hash_info, field++, - PyLong_FromLong(hashfunc->seed_bits)); - PyStructSequence_SET_ITEM(hash_info, field++, - PyLong_FromLong(Py_HASH_CUTOFF)); - if (_PyErr_Occurred(tstate)) { - Py_CLEAR(hash_info); - return NULL; - } - return hash_info; -} -/*[clinic input] -sys.getrecursionlimit - -Return the current value of the recursion limit. - -The recursion limit is the maximum depth of the Python interpreter -stack. This limit prevents infinite recursion from causing an overflow -of the C stack and crashing Python. -[clinic start generated code]*/ - -static PyObject * -sys_getrecursionlimit_impl(PyObject *module) -/*[clinic end generated code: output=d571fb6b4549ef2e input=1c6129fd2efaeea8]*/ -{ - return PyLong_FromLong(Py_GetRecursionLimit()); -} - -#ifdef MS_WINDOWS - -static PyTypeObject WindowsVersionType = {0, 0, 0, 0, 0, 0}; - -static PyStructSequence_Field windows_version_fields[] = { - {"major", "Major version number"}, - {"minor", "Minor version number"}, - {"build", "Build number"}, - {"platform", "Operating system platform"}, - {"service_pack", "Latest Service Pack installed on the system"}, - {"service_pack_major", "Service Pack major version number"}, - {"service_pack_minor", "Service Pack minor version number"}, - {"suite_mask", "Bit mask identifying available product suites"}, - {"product_type", "System product type"}, - {"platform_version", "Diagnostic version number"}, - {0} -}; - -static PyStructSequence_Desc windows_version_desc = { - "sys.getwindowsversion", /* name */ - sys_getwindowsversion__doc__, /* doc */ - windows_version_fields, /* fields */ - 5 /* For backward compatibility, - only the first 5 items are accessible - via indexing, the rest are name only */ -}; - -/* Disable deprecation warnings about GetVersionEx as the result is - being passed straight through to the caller, who is responsible for - using it correctly. */ -#pragma warning(push) -#pragma warning(disable:4996) - -/*[clinic input] -sys.getwindowsversion - -Return info about the running version of Windows as a named tuple. - -The members are named: major, minor, build, platform, service_pack, -service_pack_major, service_pack_minor, suite_mask, product_type and -platform_version. For backward compatibility, only the first 5 items -are available by indexing. All elements are numbers, except -service_pack and platform_type which are strings, and platform_version -which is a 3-tuple. Platform is always 2. Product_type may be 1 for a -workstation, 2 for a domain controller, 3 for a server. -Platform_version is a 3-tuple containing a version number that is -intended for identifying the OS rather than feature detection. -[clinic start generated code]*/ - -static PyObject * -sys_getwindowsversion_impl(PyObject *module) -/*[clinic end generated code: output=1ec063280b932857 input=73a228a328fee63a]*/ -{ - PyObject *version; - int pos = 0; - OSVERSIONINFOEXW ver; - DWORD realMajor, realMinor, realBuild; - HANDLE hKernel32; - wchar_t kernel32_path[MAX_PATH]; - LPVOID verblock; - DWORD verblock_size; - - ver.dwOSVersionInfoSize = sizeof(ver); - if (!GetVersionExW((OSVERSIONINFOW*) &ver)) - return PyErr_SetFromWindowsErr(0); - - version = PyStructSequence_New(&WindowsVersionType); - if (version == NULL) - return NULL; - - PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.dwMajorVersion)); - PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.dwMinorVersion)); - PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.dwBuildNumber)); - PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.dwPlatformId)); - PyStructSequence_SET_ITEM(version, pos++, PyUnicode_FromWideChar(ver.szCSDVersion, -1)); - PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.wServicePackMajor)); - PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.wServicePackMinor)); - PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.wSuiteMask)); - PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.wProductType)); - - realMajor = ver.dwMajorVersion; - realMinor = ver.dwMinorVersion; - realBuild = ver.dwBuildNumber; - - // GetVersion will lie if we are running in a compatibility mode. - // We need to read the version info from a system file resource - // to accurately identify the OS version. If we fail for any reason, - // just return whatever GetVersion said. - Py_BEGIN_ALLOW_THREADS - hKernel32 = GetModuleHandleW(L"kernel32.dll"); - Py_END_ALLOW_THREADS - if (hKernel32 && GetModuleFileNameW(hKernel32, kernel32_path, MAX_PATH) && - (verblock_size = GetFileVersionInfoSizeExW(0, kernel32_path, NULL)) && - (verblock = PyMem_RawMalloc(verblock_size))) { - VS_FIXEDFILEINFO *ffi; - UINT ffi_len; - - if (GetFileVersionInfoExW(0, kernel32_path, 0, verblock_size, verblock) && - VerQueryValueW(verblock, L"", (LPVOID)&ffi, &ffi_len)) { - realMajor = HIWORD(ffi->dwProductVersionMS); - realMinor = LOWORD(ffi->dwProductVersionMS); - realBuild = HIWORD(ffi->dwProductVersionLS); - } - PyMem_RawFree(verblock); - } - PyStructSequence_SET_ITEM(version, pos++, Py_BuildValue("(kkk)", - realMajor, - realMinor, - realBuild - )); - - if (PyErr_Occurred()) { - Py_DECREF(version); - return NULL; - } - return version; -} - -#pragma warning(pop) - -/*[clinic input] -sys._enablelegacywindowsfsencoding - -Changes the default filesystem encoding to mbcs:replace. - -This is done for consistency with earlier versions of Python. See PEP -529 for more information. - -This is equivalent to defining the PYTHONLEGACYWINDOWSFSENCODING -environment variable before launching Python. -[clinic start generated code]*/ - -static PyObject * -sys__enablelegacywindowsfsencoding_impl(PyObject *module) -/*[clinic end generated code: output=f5c3855b45e24fe9 input=2bfa931a20704492]*/ -{ - if (_PyUnicode_EnableLegacyWindowsFSEncoding() < 0) { - return NULL; - } - Py_RETURN_NONE; -} - -#endif /* MS_WINDOWS */ - -#ifdef HAVE_DLOPEN - -/*[clinic input] -sys.setdlopenflags - - flags as new_val: int - / - -Set the flags used by the interpreter for dlopen calls. - -This is used, for example, when the interpreter loads extension -modules. Among other things, this will enable a lazy resolving of -symbols when importing a module, if called as sys.setdlopenflags(0). -To share symbols across extension modules, call as -sys.setdlopenflags(os.RTLD_GLOBAL). Symbolic names for the flag -modules can be found in the os module (RTLD_xxx constants, e.g. -os.RTLD_LAZY). -[clinic start generated code]*/ - -static PyObject * -sys_setdlopenflags_impl(PyObject *module, int new_val) -/*[clinic end generated code: output=ec918b7fe0a37281 input=4c838211e857a77f]*/ -{ - PyInterpreterState *interp = _PyInterpreterState_GET(); - interp->dlopenflags = new_val; - Py_RETURN_NONE; -} - - -/*[clinic input] -sys.getdlopenflags - -Return the current value of the flags that are used for dlopen calls. - -The flag constants are defined in the os module. -[clinic start generated code]*/ - -static PyObject * -sys_getdlopenflags_impl(PyObject *module) -/*[clinic end generated code: output=e92cd1bc5005da6e input=dc4ea0899c53b4b6]*/ -{ - PyInterpreterState *interp = _PyInterpreterState_GET(); - return PyLong_FromLong(interp->dlopenflags); -} - -#endif /* HAVE_DLOPEN */ - -#ifdef USE_MALLOPT -/* Link with -lmalloc (or -lmpc) on an SGI */ -#include <malloc.h> - -/*[clinic input] -sys.mdebug - - flag: int - / -[clinic start generated code]*/ - -static PyObject * -sys_mdebug_impl(PyObject *module, int flag) -/*[clinic end generated code: output=5431d545847c3637 input=151d150ae1636f8a]*/ -{ - int flag; - mallopt(M_DEBUG, flag); - Py_RETURN_NONE; -} -#endif /* USE_MALLOPT */ - -size_t -_PySys_GetSizeOf(PyObject *o) -{ - PyObject *res = NULL; - PyObject *method; - Py_ssize_t size; - PyThreadState *tstate = _PyThreadState_GET(); - - /* Make sure the type is initialized. float gets initialized late */ - if (PyType_Ready(Py_TYPE(o)) < 0) { - return (size_t)-1; - } - - method = _PyObject_LookupSpecial(o, &PyId___sizeof__); - if (method == NULL) { - if (!_PyErr_Occurred(tstate)) { - _PyErr_Format(tstate, PyExc_TypeError, - "Type %.100s doesn't define __sizeof__", - Py_TYPE(o)->tp_name); - } - } - else { - res = _PyObject_CallNoArg(method); - Py_DECREF(method); - } - - if (res == NULL) - return (size_t)-1; - - size = PyLong_AsSsize_t(res); - Py_DECREF(res); - if (size == -1 && _PyErr_Occurred(tstate)) - return (size_t)-1; - - if (size < 0) { - _PyErr_SetString(tstate, PyExc_ValueError, - "__sizeof__() should return >= 0"); - return (size_t)-1; - } - - /* add gc_head size */ - if (_PyObject_IS_GC(o)) - return ((size_t)size) + sizeof(PyGC_Head); - return (size_t)size; -} - -static PyObject * -sys_getsizeof(PyObject *self, PyObject *args, PyObject *kwds) -{ - static char *kwlist[] = {"object", "default", 0}; - size_t size; - PyObject *o, *dflt = NULL; - PyThreadState *tstate = _PyThreadState_GET(); - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:getsizeof", - kwlist, &o, &dflt)) { - return NULL; - } - - size = _PySys_GetSizeOf(o); - - if (size == (size_t)-1 && _PyErr_Occurred(tstate)) { - /* Has a default value been given */ - if (dflt != NULL && _PyErr_ExceptionMatches(tstate, PyExc_TypeError)) { - _PyErr_Clear(tstate); - Py_INCREF(dflt); - return dflt; - } - else - return NULL; - } - - return PyLong_FromSize_t(size); -} - -PyDoc_STRVAR(getsizeof_doc, -"getsizeof(object [, default]) -> int\n\ -\n\ -Return the size of object in bytes."); - -/*[clinic input] -sys.getrefcount -> Py_ssize_t - - object: object - / - -Return the reference count of object. - -The count returned is generally one higher than you might expect, -because it includes the (temporary) reference as an argument to -getrefcount(). -[clinic start generated code]*/ - -static Py_ssize_t -sys_getrefcount_impl(PyObject *module, PyObject *object) -/*[clinic end generated code: output=5fd477f2264b85b2 input=bf474efd50a21535]*/ -{ - return Py_REFCNT(object); -} - -#ifdef Py_REF_DEBUG -/*[clinic input] -sys.gettotalrefcount -> Py_ssize_t -[clinic start generated code]*/ - -static Py_ssize_t -sys_gettotalrefcount_impl(PyObject *module) -/*[clinic end generated code: output=4103886cf17c25bc input=53b744faa5d2e4f6]*/ -{ - return _Py_GetRefTotal(); -} -#endif /* Py_REF_DEBUG */ - -/*[clinic input] -sys.getallocatedblocks -> Py_ssize_t - -Return the number of memory blocks currently allocated. -[clinic start generated code]*/ - -static Py_ssize_t -sys_getallocatedblocks_impl(PyObject *module) -/*[clinic end generated code: output=f0c4e873f0b6dcf7 input=dab13ee346a0673e]*/ -{ - return _Py_GetAllocatedBlocks(); -} - - -/*[clinic input] -sys._getframe - - depth: int = 0 - / - -Return a frame object from the call stack. - -If optional integer depth is given, return the frame object that many -calls below the top of the stack. If that is deeper than the call -stack, ValueError is raised. The default for depth is zero, returning -the frame at the top of the call stack. - -This function should be used for internal and specialized purposes -only. -[clinic start generated code]*/ - -static PyObject * -sys__getframe_impl(PyObject *module, int depth) -/*[clinic end generated code: output=d438776c04d59804 input=c1be8a6464b11ee5]*/ -{ - PyThreadState *tstate = _PyThreadState_GET(); - PyFrameObject *f = PyThreadState_GetFrame(tstate); - - if (_PySys_Audit(tstate, "sys._getframe", "O", f) < 0) { - Py_DECREF(f); - return NULL; - } - - while (depth > 0 && f != NULL) { - PyFrameObject *back = PyFrame_GetBack(f); - Py_DECREF(f); - f = back; - --depth; - } - if (f == NULL) { - _PyErr_SetString(tstate, PyExc_ValueError, - "call stack is not deep enough"); - return NULL; - } - return (PyObject*)f; -} - -/*[clinic input] -sys._current_frames - -Return a dict mapping each thread's thread id to its current stack frame. - -This function should be used for specialized purposes only. -[clinic start generated code]*/ - -static PyObject * -sys__current_frames_impl(PyObject *module) -/*[clinic end generated code: output=d2a41ac0a0a3809a input=2a9049c5f5033691]*/ -{ - return _PyThread_CurrentFrames(); -} - -/*[clinic input] -sys._current_exceptions - -Return a dict mapping each thread's identifier to its current raised exception. - -This function should be used for specialized purposes only. -[clinic start generated code]*/ - -static PyObject * -sys__current_exceptions_impl(PyObject *module) -/*[clinic end generated code: output=2ccfd838c746f0ba input=0e91818fbf2edc1f]*/ -{ - return _PyThread_CurrentExceptions(); -} - -/*[clinic input] -sys.call_tracing - - func: object - args as funcargs: object(subclass_of='&PyTuple_Type') - / - -Call func(*args), while tracing is enabled. - -The tracing state is saved, and restored afterwards. This is intended -to be called from a debugger from a checkpoint, to recursively debug -some other code. -[clinic start generated code]*/ - -static PyObject * -sys_call_tracing_impl(PyObject *module, PyObject *func, PyObject *funcargs) -/*[clinic end generated code: output=7e4999853cd4e5a6 input=5102e8b11049f92f]*/ -{ - return _PyEval_CallTracing(func, funcargs); -} - - -#ifdef __cplusplus -extern "C" { -#endif - -/*[clinic input] -sys._debugmallocstats - -Print summary info to stderr about the state of pymalloc's structures. - -In Py_DEBUG mode, also perform some expensive internal consistency -checks. -[clinic start generated code]*/ - -static PyObject * -sys__debugmallocstats_impl(PyObject *module) -/*[clinic end generated code: output=ec3565f8c7cee46a input=33c0c9c416f98424]*/ -{ -#ifdef WITH_PYMALLOC - if (_PyObject_DebugMallocStats(stderr)) { - fputc('\n', stderr); - } -#endif - _PyObject_DebugTypeStats(stderr); - - Py_RETURN_NONE; -} - -#ifdef Py_TRACE_REFS -/* Defined in objects.c because it uses static globals in that file */ -extern PyObject *_Py_GetObjects(PyObject *, PyObject *); -#endif - -#ifdef DYNAMIC_EXECUTION_PROFILE -/* Defined in ceval.c because it uses static globals in that file */ -extern PyObject *_Py_GetDXProfile(PyObject *, PyObject *); -#endif - -#ifdef __cplusplus -} -#endif - - -/*[clinic input] -sys._clear_type_cache - -Clear the internal type lookup cache. -[clinic start generated code]*/ - -static PyObject * -sys__clear_type_cache_impl(PyObject *module) -/*[clinic end generated code: output=20e48ca54a6f6971 input=127f3e04a8d9b555]*/ -{ - PyType_ClearCache(); - Py_RETURN_NONE; -} - -/*[clinic input] -sys.is_finalizing - -Return True if Python is exiting. -[clinic start generated code]*/ - -static PyObject * -sys_is_finalizing_impl(PyObject *module) -/*[clinic end generated code: output=735b5ff7962ab281 input=f0df747a039948a5]*/ -{ - return PyBool_FromLong(_Py_IsFinalizing()); -} - -#ifdef ANDROID_API_LEVEL -/*[clinic input] -sys.getandroidapilevel - -Return the build time API version of Android as an integer. -[clinic start generated code]*/ - -static PyObject * -sys_getandroidapilevel_impl(PyObject *module) -/*[clinic end generated code: output=214abf183a1c70c1 input=3e6d6c9fcdd24ac6]*/ -{ - return PyLong_FromLong(ANDROID_API_LEVEL); -} -#endif /* ANDROID_API_LEVEL */ - - -/*[clinic input] -sys._deactivate_opcache - -Deactivate the opcode cache permanently -[clinic start generated code]*/ - -static PyObject * -sys__deactivate_opcache_impl(PyObject *module) -/*[clinic end generated code: output=00e20982bd012122 input=501eac146735ccf9]*/ -{ - _PyEval_DeactivateOpCache(); - Py_RETURN_NONE; -} - - -static PyMethodDef sys_methods[] = { - /* Might as well keep this in alphabetic order */ - SYS_ADDAUDITHOOK_METHODDEF - {"audit", (PyCFunction)(void(*)(void))sys_audit, METH_FASTCALL, audit_doc }, - {"breakpointhook", (PyCFunction)(void(*)(void))sys_breakpointhook, - METH_FASTCALL | METH_KEYWORDS, breakpointhook_doc}, - SYS__CLEAR_TYPE_CACHE_METHODDEF - SYS__CURRENT_FRAMES_METHODDEF - SYS__CURRENT_EXCEPTIONS_METHODDEF - SYS_DISPLAYHOOK_METHODDEF - SYS_EXC_INFO_METHODDEF - SYS_EXCEPTHOOK_METHODDEF - SYS_EXIT_METHODDEF - SYS_GETDEFAULTENCODING_METHODDEF - SYS_GETDLOPENFLAGS_METHODDEF - SYS_GETALLOCATEDBLOCKS_METHODDEF -#ifdef DYNAMIC_EXECUTION_PROFILE - {"getdxp", _Py_GetDXProfile, METH_VARARGS}, -#endif - SYS_GETFILESYSTEMENCODING_METHODDEF - SYS_GETFILESYSTEMENCODEERRORS_METHODDEF -#ifdef Py_TRACE_REFS - {"getobjects", _Py_GetObjects, METH_VARARGS}, -#endif - SYS_GETTOTALREFCOUNT_METHODDEF - SYS_GETREFCOUNT_METHODDEF - SYS_GETRECURSIONLIMIT_METHODDEF - {"getsizeof", (PyCFunction)(void(*)(void))sys_getsizeof, - METH_VARARGS | METH_KEYWORDS, getsizeof_doc}, - SYS__GETFRAME_METHODDEF - SYS_GETWINDOWSVERSION_METHODDEF - SYS__ENABLELEGACYWINDOWSFSENCODING_METHODDEF - SYS_INTERN_METHODDEF - SYS_IS_FINALIZING_METHODDEF - SYS_MDEBUG_METHODDEF - SYS_SETSWITCHINTERVAL_METHODDEF - SYS_GETSWITCHINTERVAL_METHODDEF - SYS_SETDLOPENFLAGS_METHODDEF - {"setprofile", sys_setprofile, METH_O, setprofile_doc}, - SYS_GETPROFILE_METHODDEF - SYS_SETRECURSIONLIMIT_METHODDEF - {"settrace", sys_settrace, METH_O, settrace_doc}, - SYS_GETTRACE_METHODDEF - SYS_CALL_TRACING_METHODDEF - SYS__DEBUGMALLOCSTATS_METHODDEF - SYS_SET_COROUTINE_ORIGIN_TRACKING_DEPTH_METHODDEF - SYS_GET_COROUTINE_ORIGIN_TRACKING_DEPTH_METHODDEF - {"set_asyncgen_hooks", (PyCFunction)(void(*)(void))sys_set_asyncgen_hooks, - METH_VARARGS | METH_KEYWORDS, set_asyncgen_hooks_doc}, - SYS_GET_ASYNCGEN_HOOKS_METHODDEF - SYS_GETANDROIDAPILEVEL_METHODDEF - SYS_UNRAISABLEHOOK_METHODDEF - SYS__DEACTIVATE_OPCACHE_METHODDEF - {NULL, NULL} /* sentinel */ -}; - - -static PyObject * -list_builtin_module_names(void) -{ - PyObject *list = PyList_New(0); - if (list == NULL) { - return NULL; - } - for (Py_ssize_t i = 0; PyImport_Inittab[i].name != NULL; i++) { - PyObject *name = PyUnicode_FromString(PyImport_Inittab[i].name); - if (name == NULL) { - goto error; - } - if (PyList_Append(list, name) < 0) { - Py_DECREF(name); - goto error; - } - Py_DECREF(name); - } - if (PyList_Sort(list) != 0) { - goto error; - } - PyObject *tuple = PyList_AsTuple(list); - Py_DECREF(list); - return tuple; - -error: - Py_DECREF(list); - return NULL; -} - - -static PyObject * -list_stdlib_module_names(void) -{ - Py_ssize_t len = Py_ARRAY_LENGTH(_Py_stdlib_module_names); - PyObject *names = PyTuple_New(len); - if (names == NULL) { - return NULL; - } - - for (Py_ssize_t i = 0; i < len; i++) { - PyObject *name = PyUnicode_FromString(_Py_stdlib_module_names[i]); - if (name == NULL) { - Py_DECREF(names); - return NULL; - } - PyTuple_SET_ITEM(names, i, name); - } - - PyObject *set = PyObject_CallFunction((PyObject *)&PyFrozenSet_Type, - "(O)", names); - Py_DECREF(names); - return set; -} - - -/* Pre-initialization support for sys.warnoptions and sys._xoptions - * - * Modern internal code paths: - * These APIs get called after _Py_InitializeCore and get to use the - * regular CPython list, dict, and unicode APIs. - * - * Legacy embedding code paths: - * The multi-phase initialization API isn't public yet, so embedding - * apps still need to be able configure sys.warnoptions and sys._xoptions - * before they call Py_Initialize. To support this, we stash copies of - * the supplied wchar * sequences in linked lists, and then migrate the - * contents of those lists to the sys module in _PyInitializeCore. - * - */ - -struct _preinit_entry { - wchar_t *value; - struct _preinit_entry *next; -}; - -typedef struct _preinit_entry *_Py_PreInitEntry; - -static _Py_PreInitEntry _preinit_warnoptions = NULL; -static _Py_PreInitEntry _preinit_xoptions = NULL; - -static _Py_PreInitEntry -_alloc_preinit_entry(const wchar_t *value) -{ - /* To get this to work, we have to initialize the runtime implicitly */ - _PyRuntime_Initialize(); - - /* Force default allocator, so we can ensure that it also gets used to - * destroy the linked list in _clear_preinit_entries. - */ - PyMemAllocatorEx old_alloc; - _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - - _Py_PreInitEntry node = PyMem_RawCalloc(1, sizeof(*node)); - if (node != NULL) { - node->value = _PyMem_RawWcsdup(value); - if (node->value == NULL) { - PyMem_RawFree(node); - node = NULL; - }; - }; - - PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - return node; -} - -static int -_append_preinit_entry(_Py_PreInitEntry *optionlist, const wchar_t *value) -{ - _Py_PreInitEntry new_entry = _alloc_preinit_entry(value); - if (new_entry == NULL) { - return -1; - } - /* We maintain the linked list in this order so it's easy to play back - * the add commands in the same order later on in _Py_InitializeCore - */ - _Py_PreInitEntry last_entry = *optionlist; - if (last_entry == NULL) { - *optionlist = new_entry; - } else { - while (last_entry->next != NULL) { - last_entry = last_entry->next; - } - last_entry->next = new_entry; - } - return 0; -} - -static void -_clear_preinit_entries(_Py_PreInitEntry *optionlist) -{ - _Py_PreInitEntry current = *optionlist; - *optionlist = NULL; - /* Deallocate the nodes and their contents using the default allocator */ - PyMemAllocatorEx old_alloc; - _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - while (current != NULL) { - _Py_PreInitEntry next = current->next; - PyMem_RawFree(current->value); - PyMem_RawFree(current); - current = next; - } - PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); -} - - -PyStatus -_PySys_ReadPreinitWarnOptions(PyWideStringList *options) -{ - PyStatus status; - _Py_PreInitEntry entry; - - for (entry = _preinit_warnoptions; entry != NULL; entry = entry->next) { - status = PyWideStringList_Append(options, entry->value); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - } - - _clear_preinit_entries(&_preinit_warnoptions); - return _PyStatus_OK(); -} - - -PyStatus -_PySys_ReadPreinitXOptions(PyConfig *config) -{ - PyStatus status; - _Py_PreInitEntry entry; - - for (entry = _preinit_xoptions; entry != NULL; entry = entry->next) { - status = PyWideStringList_Append(&config->xoptions, entry->value); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - } - - _clear_preinit_entries(&_preinit_xoptions); - return _PyStatus_OK(); -} - - -static PyObject * -get_warnoptions(PyThreadState *tstate) -{ - PyObject *warnoptions = sys_get_object_id(tstate, &PyId_warnoptions); - if (warnoptions == NULL || !PyList_Check(warnoptions)) { - /* PEP432 TODO: we can reach this if warnoptions is NULL in the main - * interpreter config. When that happens, we need to properly set - * the `warnoptions` reference in the main interpreter config as well. - * - * For Python 3.7, we shouldn't be able to get here due to the - * combination of how _PyMainInterpreter_ReadConfig and _PySys_EndInit - * work, but we expect 3.8+ to make the _PyMainInterpreter_ReadConfig - * call optional for embedding applications, thus making this - * reachable again. - */ - warnoptions = PyList_New(0); - if (warnoptions == NULL) { - return NULL; - } - if (sys_set_object_id(tstate->interp, &PyId_warnoptions, warnoptions)) { - Py_DECREF(warnoptions); - return NULL; - } - Py_DECREF(warnoptions); - } - return warnoptions; -} - -void -PySys_ResetWarnOptions(void) -{ - PyThreadState *tstate = _PyThreadState_GET(); - if (tstate == NULL) { - _clear_preinit_entries(&_preinit_warnoptions); - return; - } - - PyObject *warnoptions = sys_get_object_id(tstate, &PyId_warnoptions); - if (warnoptions == NULL || !PyList_Check(warnoptions)) - return; - PyList_SetSlice(warnoptions, 0, PyList_GET_SIZE(warnoptions), NULL); -} - -static int -_PySys_AddWarnOptionWithError(PyThreadState *tstate, PyObject *option) -{ - PyObject *warnoptions = get_warnoptions(tstate); - if (warnoptions == NULL) { - return -1; - } - if (PyList_Append(warnoptions, option)) { - return -1; - } - return 0; -} - -void -PySys_AddWarnOptionUnicode(PyObject *option) -{ - PyThreadState *tstate = _PyThreadState_GET(); - if (_PySys_AddWarnOptionWithError(tstate, option) < 0) { - /* No return value, therefore clear error state if possible */ - if (tstate) { - _PyErr_Clear(tstate); - } - } -} - -void -PySys_AddWarnOption(const wchar_t *s) -{ - PyThreadState *tstate = _PyThreadState_GET(); - if (tstate == NULL) { - _append_preinit_entry(&_preinit_warnoptions, s); - return; - } - PyObject *unicode; - unicode = PyUnicode_FromWideChar(s, -1); - if (unicode == NULL) - return; - PySys_AddWarnOptionUnicode(unicode); - Py_DECREF(unicode); -} - -int -PySys_HasWarnOptions(void) -{ - PyThreadState *tstate = _PyThreadState_GET(); - PyObject *warnoptions = sys_get_object_id(tstate, &PyId_warnoptions); - return (warnoptions != NULL && PyList_Check(warnoptions) - && PyList_GET_SIZE(warnoptions) > 0); -} - -static PyObject * -get_xoptions(PyThreadState *tstate) -{ - PyObject *xoptions = sys_get_object_id(tstate, &PyId__xoptions); - if (xoptions == NULL || !PyDict_Check(xoptions)) { - /* PEP432 TODO: we can reach this if xoptions is NULL in the main - * interpreter config. When that happens, we need to properly set - * the `xoptions` reference in the main interpreter config as well. - * - * For Python 3.7, we shouldn't be able to get here due to the - * combination of how _PyMainInterpreter_ReadConfig and _PySys_EndInit - * work, but we expect 3.8+ to make the _PyMainInterpreter_ReadConfig - * call optional for embedding applications, thus making this - * reachable again. - */ - xoptions = PyDict_New(); - if (xoptions == NULL) { - return NULL; - } - if (sys_set_object_id(tstate->interp, &PyId__xoptions, xoptions)) { - Py_DECREF(xoptions); - return NULL; - } - Py_DECREF(xoptions); - } - return xoptions; -} - -static int -_PySys_AddXOptionWithError(const wchar_t *s) -{ - PyObject *name = NULL, *value = NULL; - - PyThreadState *tstate = _PyThreadState_GET(); - PyObject *opts = get_xoptions(tstate); - if (opts == NULL) { - goto error; - } - - const wchar_t *name_end = wcschr(s, L'='); - if (!name_end) { - name = PyUnicode_FromWideChar(s, -1); - value = Py_True; - Py_INCREF(value); - } - else { - name = PyUnicode_FromWideChar(s, name_end - s); - value = PyUnicode_FromWideChar(name_end + 1, -1); - } - if (name == NULL || value == NULL) { - goto error; - } - if (PyDict_SetItem(opts, name, value) < 0) { - goto error; - } - Py_DECREF(name); - Py_DECREF(value); - return 0; - -error: - Py_XDECREF(name); - Py_XDECREF(value); - return -1; -} - -void -PySys_AddXOption(const wchar_t *s) -{ - PyThreadState *tstate = _PyThreadState_GET(); - if (tstate == NULL) { - _append_preinit_entry(&_preinit_xoptions, s); - return; - } - if (_PySys_AddXOptionWithError(s) < 0) { - /* No return value, therefore clear error state if possible */ - _PyErr_Clear(tstate); - } -} - -PyObject * -PySys_GetXOptions(void) -{ - PyThreadState *tstate = _PyThreadState_GET(); - return get_xoptions(tstate); -} - -/* XXX This doc string is too long to be a single string literal in VC++ 5.0. - Two literals concatenated works just fine. If you have a K&R compiler - or other abomination that however *does* understand longer strings, - get rid of the !!! comment in the middle and the quotes that surround it. */ -PyDoc_VAR(sys_doc) = -PyDoc_STR( -"This module provides access to some objects used or maintained by the\n\ -interpreter and to functions that interact strongly with the interpreter.\n\ -\n\ -Dynamic objects:\n\ -\n\ -argv -- command line arguments; argv[0] is the script pathname if known\n\ -path -- module search path; path[0] is the script directory, else ''\n\ -modules -- dictionary of loaded modules\n\ -\n\ -displayhook -- called to show results in an interactive session\n\ -excepthook -- called to handle any uncaught exception other than SystemExit\n\ - To customize printing in an interactive session or to install a custom\n\ - top-level exception handler, assign other functions to replace these.\n\ -\n\ -stdin -- standard input file object; used by input()\n\ -stdout -- standard output file object; used by print()\n\ -stderr -- standard error object; used for error messages\n\ - By assigning other file objects (or objects that behave like files)\n\ - to these, it is possible to redirect all of the interpreter's I/O.\n\ -\n\ -last_type -- type of last uncaught exception\n\ -last_value -- value of last uncaught exception\n\ -last_traceback -- traceback of last uncaught exception\n\ - These three are only available in an interactive session after a\n\ - traceback has been printed.\n\ -" -) -/* concatenating string here */ -PyDoc_STR( -"\n\ -Static objects:\n\ -\n\ -builtin_module_names -- tuple of module names built into this interpreter\n\ -copyright -- copyright notice pertaining to this interpreter\n\ -exec_prefix -- prefix used to find the machine-specific Python library\n\ -executable -- absolute path of the executable binary of the Python interpreter\n\ -float_info -- a named tuple with information about the float implementation.\n\ -float_repr_style -- string indicating the style of repr() output for floats\n\ -hash_info -- a named tuple with information about the hash algorithm.\n\ -hexversion -- version information encoded as a single integer\n\ -implementation -- Python implementation information.\n\ -int_info -- a named tuple with information about the int implementation.\n\ -maxsize -- the largest supported length of containers.\n\ -maxunicode -- the value of the largest Unicode code point\n\ -platform -- platform identifier\n\ -prefix -- prefix used to find the Python library\n\ -thread_info -- a named tuple with information about the thread implementation.\n\ -version -- the version of this interpreter as a string\n\ -version_info -- version information as a named tuple\n\ -" -) -#ifdef MS_COREDLL -/* concatenating string here */ -PyDoc_STR( -"dllhandle -- [Windows only] integer handle of the Python DLL\n\ -winver -- [Windows only] version number of the Python DLL\n\ -" -) -#endif /* MS_COREDLL */ -#ifdef MS_WINDOWS -/* concatenating string here */ -PyDoc_STR( -"_enablelegacywindowsfsencoding -- [Windows only]\n\ -" -) -#endif -PyDoc_STR( -"__stdin__ -- the original stdin; don't touch!\n\ -__stdout__ -- the original stdout; don't touch!\n\ -__stderr__ -- the original stderr; don't touch!\n\ -__displayhook__ -- the original displayhook; don't touch!\n\ -__excepthook__ -- the original excepthook; don't touch!\n\ -\n\ -Functions:\n\ -\n\ -displayhook() -- print an object to the screen, and save it in builtins._\n\ -excepthook() -- print an exception and its traceback to sys.stderr\n\ -exc_info() -- return thread-safe information about the current exception\n\ -exit() -- exit the interpreter by raising SystemExit\n\ -getdlopenflags() -- returns flags to be used for dlopen() calls\n\ -getprofile() -- get the global profiling function\n\ -getrefcount() -- return the reference count for an object (plus one :-)\n\ -getrecursionlimit() -- return the max recursion depth for the interpreter\n\ -getsizeof() -- return the size of an object in bytes\n\ -gettrace() -- get the global debug tracing function\n\ -setdlopenflags() -- set the flags to be used for dlopen() calls\n\ -setprofile() -- set the global profiling function\n\ -setrecursionlimit() -- set the max recursion depth for the interpreter\n\ -settrace() -- set the global debug tracing function\n\ -" -) -/* end of sys_doc */ ; - - -PyDoc_STRVAR(flags__doc__, -"sys.flags\n\ -\n\ -Flags provided through command line arguments or environment vars."); - -static PyTypeObject FlagsType; - -static PyStructSequence_Field flags_fields[] = { - {"debug", "-d"}, - {"inspect", "-i"}, - {"interactive", "-i"}, - {"optimize", "-O or -OO"}, - {"dont_write_bytecode", "-B"}, - {"no_user_site", "-s"}, - {"no_site", "-S"}, - {"ignore_environment", "-E"}, - {"verbose", "-v"}, - {"bytes_warning", "-b"}, - {"quiet", "-q"}, - {"hash_randomization", "-R"}, - {"isolated", "-I"}, - {"dev_mode", "-X dev"}, - {"utf8_mode", "-X utf8"}, - {"warn_default_encoding", "-X warn_default_encoding"}, - {0} -}; - -static PyStructSequence_Desc flags_desc = { - "sys.flags", /* name */ - flags__doc__, /* doc */ - flags_fields, /* fields */ - 16 -}; - -static int -set_flags_from_config(PyInterpreterState *interp, PyObject *flags) -{ - const PyPreConfig *preconfig = &interp->runtime->preconfig; - const PyConfig *config = _PyInterpreterState_GetConfig(interp); - - // _PySys_UpdateConfig() modifies sys.flags in-place: - // Py_XDECREF() is needed in this case. - Py_ssize_t pos = 0; -#define SetFlagObj(expr) \ - do { \ - PyObject *value = (expr); \ - if (value == NULL) { \ - return -1; \ - } \ - Py_XDECREF(PyStructSequence_GET_ITEM(flags, pos)); \ - PyStructSequence_SET_ITEM(flags, pos, value); \ - pos++; \ - } while (0) -#define SetFlag(expr) SetFlagObj(PyLong_FromLong(expr)) - - SetFlag(config->parser_debug); - SetFlag(config->inspect); - SetFlag(config->interactive); - SetFlag(config->optimization_level); - SetFlag(!config->write_bytecode); - SetFlag(!config->user_site_directory); - SetFlag(!config->site_import); - SetFlag(!config->use_environment); - SetFlag(config->verbose); - SetFlag(config->bytes_warning); - SetFlag(config->quiet); - SetFlag(config->use_hash_seed == 0 || config->hash_seed != 0); - SetFlag(config->isolated); - SetFlagObj(PyBool_FromLong(config->dev_mode)); - SetFlag(preconfig->utf8_mode); - SetFlag(config->warn_default_encoding); -#undef SetFlagObj -#undef SetFlag - return 0; -} - - -static PyObject* -make_flags(PyInterpreterState *interp) -{ - PyObject *flags = PyStructSequence_New(&FlagsType); - if (flags == NULL) { - return NULL; - } - - if (set_flags_from_config(interp, flags) < 0) { - Py_DECREF(flags); - return NULL; - } - return flags; -} - - -PyDoc_STRVAR(version_info__doc__, -"sys.version_info\n\ -\n\ -Version information as a named tuple."); - -static PyTypeObject VersionInfoType; - -static PyStructSequence_Field version_info_fields[] = { - {"major", "Major release number"}, - {"minor", "Minor release number"}, - {"micro", "Patch release number"}, - {"releaselevel", "'alpha', 'beta', 'candidate', or 'final'"}, - {"serial", "Serial release number"}, - {0} -}; - -static PyStructSequence_Desc version_info_desc = { - "sys.version_info", /* name */ - version_info__doc__, /* doc */ - version_info_fields, /* fields */ - 5 -}; - -static PyObject * -make_version_info(PyThreadState *tstate) -{ - PyObject *version_info; - char *s; - int pos = 0; - - version_info = PyStructSequence_New(&VersionInfoType); - if (version_info == NULL) { - return NULL; - } - - /* - * These release level checks are mutually exclusive and cover - * the field, so don't get too fancy with the pre-processor! - */ -#if PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_ALPHA - s = "alpha"; -#elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_BETA - s = "beta"; -#elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_GAMMA - s = "candidate"; -#elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_FINAL - s = "final"; -#endif - -#define SetIntItem(flag) \ - PyStructSequence_SET_ITEM(version_info, pos++, PyLong_FromLong(flag)) -#define SetStrItem(flag) \ - PyStructSequence_SET_ITEM(version_info, pos++, PyUnicode_FromString(flag)) - - SetIntItem(PY_MAJOR_VERSION); - SetIntItem(PY_MINOR_VERSION); - SetIntItem(PY_MICRO_VERSION); - SetStrItem(s); - SetIntItem(PY_RELEASE_SERIAL); -#undef SetIntItem -#undef SetStrItem - - if (_PyErr_Occurred(tstate)) { - Py_CLEAR(version_info); - return NULL; - } - return version_info; -} - -/* sys.implementation values */ -#define NAME "cpython" -const char *_PySys_ImplName = NAME; -#define MAJOR Py_STRINGIFY(PY_MAJOR_VERSION) -#define MINOR Py_STRINGIFY(PY_MINOR_VERSION) -#define TAG NAME "-" MAJOR MINOR -const char *_PySys_ImplCacheTag = TAG; -#undef NAME -#undef MAJOR -#undef MINOR -#undef TAG - -static PyObject * -make_impl_info(PyObject *version_info) -{ - int res; - PyObject *impl_info, *value, *ns; - - impl_info = PyDict_New(); - if (impl_info == NULL) - return NULL; - - /* populate the dict */ - - value = PyUnicode_FromString(_PySys_ImplName); - if (value == NULL) - goto error; - res = PyDict_SetItemString(impl_info, "name", value); - Py_DECREF(value); - if (res < 0) - goto error; - - value = PyUnicode_FromString(_PySys_ImplCacheTag); - if (value == NULL) - goto error; - res = PyDict_SetItemString(impl_info, "cache_tag", value); - Py_DECREF(value); - if (res < 0) - goto error; - - res = PyDict_SetItemString(impl_info, "version", version_info); - if (res < 0) - goto error; - - value = PyLong_FromLong(PY_VERSION_HEX); - if (value == NULL) - goto error; - res = PyDict_SetItemString(impl_info, "hexversion", value); - Py_DECREF(value); - if (res < 0) - goto error; - -#ifdef MULTIARCH - value = PyUnicode_FromString(MULTIARCH); - if (value == NULL) - goto error; - res = PyDict_SetItemString(impl_info, "_multiarch", value); - Py_DECREF(value); - if (res < 0) - goto error; -#endif - - /* dict ready */ - - ns = _PyNamespace_New(impl_info); - Py_DECREF(impl_info); - return ns; - -error: - Py_CLEAR(impl_info); - return NULL; -} - -static struct PyModuleDef sysmodule = { - PyModuleDef_HEAD_INIT, - "sys", - sys_doc, - -1, /* multiple "initialization" just copies the module dict. */ - sys_methods, - NULL, - NULL, - NULL, - NULL -}; - -/* Updating the sys namespace, returning NULL pointer on error */ -#define SET_SYS(key, value) \ - do { \ - PyObject *v = (value); \ - if (v == NULL) { \ - goto err_occurred; \ - } \ - res = PyDict_SetItemString(sysdict, key, v); \ - Py_DECREF(v); \ - if (res < 0) { \ - goto err_occurred; \ - } \ - } while (0) - -#define SET_SYS_FROM_STRING(key, value) \ - SET_SYS(key, PyUnicode_FromString(value)) - -static PyStatus -_PySys_InitCore(PyThreadState *tstate, PyObject *sysdict) -{ - PyObject *version_info; - int res; - - /* stdin/stdout/stderr are set in pylifecycle.c */ - -#define COPY_SYS_ATTR(tokey, fromkey) \ - SET_SYS(tokey, PyMapping_GetItemString(sysdict, fromkey)) - - COPY_SYS_ATTR("__displayhook__", "displayhook"); - COPY_SYS_ATTR("__excepthook__", "excepthook"); - COPY_SYS_ATTR("__breakpointhook__", "breakpointhook"); - COPY_SYS_ATTR("__unraisablehook__", "unraisablehook"); - -#undef COPY_SYS_ATTR - - SET_SYS_FROM_STRING("version", Py_GetVersion()); - SET_SYS("hexversion", PyLong_FromLong(PY_VERSION_HEX)); - SET_SYS("_git", Py_BuildValue("(szz)", "CPython", _Py_gitidentifier(), - _Py_gitversion())); - SET_SYS_FROM_STRING("_framework", _PYTHONFRAMEWORK); - SET_SYS("api_version", PyLong_FromLong(PYTHON_API_VERSION)); - SET_SYS_FROM_STRING("copyright", Py_GetCopyright()); - SET_SYS_FROM_STRING("platform", Py_GetPlatform()); - SET_SYS("maxsize", PyLong_FromSsize_t(PY_SSIZE_T_MAX)); - SET_SYS("float_info", PyFloat_GetInfo()); - SET_SYS("int_info", PyLong_GetInfo()); - /* initialize hash_info */ - if (Hash_InfoType.tp_name == NULL) { - if (PyStructSequence_InitType2(&Hash_InfoType, &hash_info_desc) < 0) { - goto type_init_failed; - } - } - SET_SYS("hash_info", get_hash_info(tstate)); - SET_SYS("maxunicode", PyLong_FromLong(0x10FFFF)); - SET_SYS("builtin_module_names", list_builtin_module_names()); - SET_SYS("stdlib_module_names", list_stdlib_module_names()); -#if PY_BIG_ENDIAN - SET_SYS_FROM_STRING("byteorder", "big"); -#else - SET_SYS_FROM_STRING("byteorder", "little"); -#endif - -#ifdef MS_COREDLL - SET_SYS("dllhandle", PyLong_FromVoidPtr(PyWin_DLLhModule)); - SET_SYS_FROM_STRING("winver", PyWin_DLLVersionString); -#endif -#ifdef ABIFLAGS - SET_SYS_FROM_STRING("abiflags", ABIFLAGS); -#endif - - /* version_info */ - if (VersionInfoType.tp_name == NULL) { - if (_PyStructSequence_InitType(&VersionInfoType, - &version_info_desc, - Py_TPFLAGS_DISALLOW_INSTANTIATION) < 0) { - goto type_init_failed; - } - } - version_info = make_version_info(tstate); - SET_SYS("version_info", version_info); - - /* implementation */ - SET_SYS("implementation", make_impl_info(version_info)); - - // sys.flags: updated in-place later by _PySys_UpdateConfig() - if (FlagsType.tp_name == 0) { - if (_PyStructSequence_InitType(&FlagsType, &flags_desc, - Py_TPFLAGS_DISALLOW_INSTANTIATION) < 0) { - goto type_init_failed; - } - } - SET_SYS("flags", make_flags(tstate->interp)); - -#if defined(MS_WINDOWS) - /* getwindowsversion */ - if (WindowsVersionType.tp_name == 0) { - if (_PyStructSequence_InitType(&WindowsVersionType, - &windows_version_desc, - Py_TPFLAGS_DISALLOW_INSTANTIATION) < 0) { - goto type_init_failed; - } - } -#endif - - /* float repr style: 0.03 (short) vs 0.029999999999999999 (legacy) */ -#ifndef PY_NO_SHORT_FLOAT_REPR - SET_SYS_FROM_STRING("float_repr_style", "short"); -#else - SET_SYS_FROM_STRING("float_repr_style", "legacy"); -#endif - - SET_SYS("thread_info", PyThread_GetInfo()); - - /* initialize asyncgen_hooks */ - if (AsyncGenHooksType.tp_name == NULL) { - if (PyStructSequence_InitType2( - &AsyncGenHooksType, &asyncgen_hooks_desc) < 0) { - goto type_init_failed; - } - } - - /* adding sys.path_hooks and sys.path_importer_cache */ - SET_SYS("meta_path", PyList_New(0)); - SET_SYS("path_importer_cache", PyDict_New()); - SET_SYS("path_hooks", PyList_New(0)); - - if (_PyErr_Occurred(tstate)) { - goto err_occurred; - } - return _PyStatus_OK(); - -type_init_failed: - return _PyStatus_ERR("failed to initialize a type"); - -err_occurred: - return _PyStatus_ERR("can't initialize sys module"); -} - -static int -sys_add_xoption(PyObject *opts, const wchar_t *s) -{ - PyObject *name, *value; - - const wchar_t *name_end = wcschr(s, L'='); - if (!name_end) { - name = PyUnicode_FromWideChar(s, -1); - value = Py_True; - Py_INCREF(value); - } - else { - name = PyUnicode_FromWideChar(s, name_end - s); - value = PyUnicode_FromWideChar(name_end + 1, -1); - } - if (name == NULL || value == NULL) { - goto error; - } - if (PyDict_SetItem(opts, name, value) < 0) { - goto error; - } - Py_DECREF(name); - Py_DECREF(value); - return 0; - -error: - Py_XDECREF(name); - Py_XDECREF(value); - return -1; -} - - -static PyObject* -sys_create_xoptions_dict(const PyConfig *config) -{ - Py_ssize_t nxoption = config->xoptions.length; - wchar_t * const * xoptions = config->xoptions.items; - PyObject *dict = PyDict_New(); - if (dict == NULL) { - return NULL; - } - - for (Py_ssize_t i=0; i < nxoption; i++) { - const wchar_t *option = xoptions[i]; - if (sys_add_xoption(dict, option) < 0) { - Py_DECREF(dict); - return NULL; - } - } - - return dict; -} - - -// Update sys attributes for a new PyConfig configuration. -// This function also adds attributes that _PySys_InitCore() didn't add. -int -_PySys_UpdateConfig(PyThreadState *tstate) -{ - PyInterpreterState *interp = tstate->interp; - PyObject *sysdict = interp->sysdict; - const PyConfig *config = _PyInterpreterState_GetConfig(interp); - int res; - -#define COPY_LIST(KEY, VALUE) \ - SET_SYS(KEY, _PyWideStringList_AsList(&(VALUE))); - -#define SET_SYS_FROM_WSTR(KEY, VALUE) \ - SET_SYS(KEY, PyUnicode_FromWideChar(VALUE, -1)); - -#define COPY_WSTR(SYS_ATTR, WSTR) \ - if (WSTR != NULL) { \ - SET_SYS_FROM_WSTR(SYS_ATTR, WSTR); \ - } - - if (config->module_search_paths_set) { - COPY_LIST("path", config->module_search_paths); - } - - COPY_WSTR("executable", config->executable); - COPY_WSTR("_base_executable", config->base_executable); - COPY_WSTR("prefix", config->prefix); - COPY_WSTR("base_prefix", config->base_prefix); - COPY_WSTR("exec_prefix", config->exec_prefix); - COPY_WSTR("base_exec_prefix", config->base_exec_prefix); - COPY_WSTR("platlibdir", config->platlibdir); - - if (config->pycache_prefix != NULL) { - SET_SYS_FROM_WSTR("pycache_prefix", config->pycache_prefix); - } else { - PyDict_SetItemString(sysdict, "pycache_prefix", Py_None); - } - - COPY_LIST("argv", config->argv); - COPY_LIST("orig_argv", config->orig_argv); - COPY_LIST("warnoptions", config->warnoptions); - - SET_SYS("_xoptions", sys_create_xoptions_dict(config)); - -#undef SET_SYS_FROM_WSTR -#undef COPY_LIST -#undef COPY_WSTR - - // sys.flags - PyObject *flags = _PySys_GetObject(interp, "flags"); // borrowed ref - if (flags == NULL) { - return -1; - } - if (set_flags_from_config(interp, flags) < 0) { - return -1; - } - - SET_SYS("dont_write_bytecode", PyBool_FromLong(!config->write_bytecode)); - - if (_PyErr_Occurred(tstate)) { - goto err_occurred; - } - - return 0; - -err_occurred: - return -1; -} - -#undef SET_SYS -#undef SET_SYS_FROM_STRING - - -/* Set up a preliminary stderr printer until we have enough - infrastructure for the io module in place. - - Use UTF-8/backslashreplace and ignore EAGAIN errors. */ -static PyStatus -_PySys_SetPreliminaryStderr(PyObject *sysdict) -{ - PyObject *pstderr = PyFile_NewStdPrinter(fileno(stderr)); - if (pstderr == NULL) { - goto error; - } - if (_PyDict_SetItemId(sysdict, &PyId_stderr, pstderr) < 0) { - goto error; - } - if (PyDict_SetItemString(sysdict, "__stderr__", pstderr) < 0) { - goto error; - } - Py_DECREF(pstderr); - return _PyStatus_OK(); - -error: - Py_XDECREF(pstderr); - return _PyStatus_ERR("can't set preliminary stderr"); -} - - -/* Create sys module without all attributes. - _PySys_UpdateConfig() should be called later to add remaining attributes. */ -PyStatus -_PySys_Create(PyThreadState *tstate, PyObject **sysmod_p) -{ - assert(!_PyErr_Occurred(tstate)); - - PyInterpreterState *interp = tstate->interp; - - PyObject *modules = PyDict_New(); - if (modules == NULL) { - goto error; - } - interp->modules = modules; - - PyObject *sysmod = _PyModule_CreateInitialized(&sysmodule, PYTHON_API_VERSION); - if (sysmod == NULL) { - return _PyStatus_ERR("failed to create a module object"); - } - - PyObject *sysdict = PyModule_GetDict(sysmod); - if (sysdict == NULL) { - goto error; - } - Py_INCREF(sysdict); - interp->sysdict = sysdict; - - if (PyDict_SetItemString(sysdict, "modules", interp->modules) < 0) { - goto error; - } - - PyStatus status = _PySys_SetPreliminaryStderr(sysdict); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - status = _PySys_InitCore(tstate, sysdict); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - if (_PyImport_FixupBuiltin(sysmod, "sys", interp->modules) < 0) { - goto error; - } - - assert(!_PyErr_Occurred(tstate)); - - *sysmod_p = sysmod; - return _PyStatus_OK(); - -error: - return _PyStatus_ERR("can't initialize sys module"); -} - - -static PyObject * -makepathobject(const wchar_t *path, wchar_t delim) -{ - int i, n; - const wchar_t *p; - PyObject *v, *w; - - n = 1; - p = path; - while ((p = wcschr(p, delim)) != NULL) { - n++; - p++; - } - v = PyList_New(n); - if (v == NULL) - return NULL; - for (i = 0; ; i++) { - p = wcschr(path, delim); - if (p == NULL) - p = path + wcslen(path); /* End of string */ - w = PyUnicode_FromWideChar(path, (Py_ssize_t)(p - path)); - if (w == NULL) { - Py_DECREF(v); - return NULL; - } - PyList_SET_ITEM(v, i, w); - if (*p == '\0') - break; - path = p+1; - } - return v; -} - -void -PySys_SetPath(const wchar_t *path) -{ - PyObject *v; - if ((v = makepathobject(path, DELIM)) == NULL) - Py_FatalError("can't create sys.path"); - PyInterpreterState *interp = _PyInterpreterState_GET(); - if (sys_set_object_id(interp, &PyId_path, v) != 0) { - Py_FatalError("can't assign sys.path"); - } - Py_DECREF(v); -} - -static PyObject * -make_sys_argv(int argc, wchar_t * const * argv) -{ - PyObject *list = PyList_New(argc); - if (list == NULL) { - return NULL; - } - - for (Py_ssize_t i = 0; i < argc; i++) { - PyObject *v = PyUnicode_FromWideChar(argv[i], -1); - if (v == NULL) { - Py_DECREF(list); - return NULL; - } - PyList_SET_ITEM(list, i, v); - } - return list; -} - -void -PySys_SetArgvEx(int argc, wchar_t **argv, int updatepath) -{ - wchar_t* empty_argv[1] = {L""}; - PyThreadState *tstate = _PyThreadState_GET(); - - if (argc < 1 || argv == NULL) { - /* Ensure at least one (empty) argument is seen */ - argv = empty_argv; - argc = 1; - } - - PyObject *av = make_sys_argv(argc, argv); - if (av == NULL) { - Py_FatalError("no mem for sys.argv"); - } - if (sys_set_object_str(tstate->interp, "argv", av) != 0) { - Py_DECREF(av); - Py_FatalError("can't assign sys.argv"); - } - Py_DECREF(av); - - if (updatepath) { - /* If argv[0] is not '-c' nor '-m', prepend argv[0] to sys.path. - If argv[0] is a symlink, use the real path. */ - const PyWideStringList argv_list = {.length = argc, .items = argv}; - PyObject *path0 = NULL; - if (_PyPathConfig_ComputeSysPath0(&argv_list, &path0)) { - if (path0 == NULL) { - Py_FatalError("can't compute path0 from argv"); - } - - PyObject *sys_path = sys_get_object_id(tstate, &PyId_path); - if (sys_path != NULL) { - if (PyList_Insert(sys_path, 0, path0) < 0) { - Py_DECREF(path0); - Py_FatalError("can't prepend path0 to sys.path"); - } - } - Py_DECREF(path0); - } - } -} - -void -PySys_SetArgv(int argc, wchar_t **argv) -{ - PySys_SetArgvEx(argc, argv, 0); -} - -/* Reimplementation of PyFile_WriteString() no calling indirectly - PyErr_CheckSignals(): avoid the call to PyObject_Str(). */ - -static int -sys_pyfile_write_unicode(PyObject *unicode, PyObject *file) -{ - if (file == NULL) - return -1; - assert(unicode != NULL); - PyObject *result = _PyObject_CallMethodIdOneArg(file, &PyId_write, unicode); - if (result == NULL) { - return -1; - } - Py_DECREF(result); - return 0; -} - -static int -sys_pyfile_write(const char *text, PyObject *file) -{ - PyObject *unicode = NULL; - int err; - - if (file == NULL) - return -1; - - unicode = PyUnicode_FromString(text); - if (unicode == NULL) - return -1; - - err = sys_pyfile_write_unicode(unicode, file); - Py_DECREF(unicode); - return err; -} - -/* APIs to write to sys.stdout or sys.stderr using a printf-like interface. - Adapted from code submitted by Just van Rossum. - - PySys_WriteStdout(format, ...) - PySys_WriteStderr(format, ...) - - The first function writes to sys.stdout; the second to sys.stderr. When - there is a problem, they write to the real (C level) stdout or stderr; - no exceptions are raised. - - PyErr_CheckSignals() is not called to avoid the execution of the Python - signal handlers: they may raise a new exception whereas sys_write() - ignores all exceptions. - - Both take a printf-style format string as their first argument followed - by a variable length argument list determined by the format string. - - *** WARNING *** - - The format should limit the total size of the formatted output string to - 1000 bytes. In particular, this means that no unrestricted "%s" formats - should occur; these should be limited using "%.<N>s where <N> is a - decimal number calculated so that <N> plus the maximum size of other - formatted text does not exceed 1000 bytes. Also watch out for "%f", - which can print hundreds of digits for very large numbers. - - */ - -static void -sys_write(_Py_Identifier *key, FILE *fp, const char *format, va_list va) -{ - PyObject *file; - PyObject *error_type, *error_value, *error_traceback; - char buffer[1001]; - int written; - PyThreadState *tstate = _PyThreadState_GET(); - - _PyErr_Fetch(tstate, &error_type, &error_value, &error_traceback); - file = sys_get_object_id(tstate, key); - written = PyOS_vsnprintf(buffer, sizeof(buffer), format, va); - if (sys_pyfile_write(buffer, file) != 0) { - _PyErr_Clear(tstate); - fputs(buffer, fp); - } - if (written < 0 || (size_t)written >= sizeof(buffer)) { - const char *truncated = "... truncated"; - if (sys_pyfile_write(truncated, file) != 0) - fputs(truncated, fp); - } - _PyErr_Restore(tstate, error_type, error_value, error_traceback); -} - -void -PySys_WriteStdout(const char *format, ...) -{ - va_list va; - - va_start(va, format); - sys_write(&PyId_stdout, stdout, format, va); - va_end(va); -} - -void -PySys_WriteStderr(const char *format, ...) -{ - va_list va; - - va_start(va, format); - sys_write(&PyId_stderr, stderr, format, va); - va_end(va); -} - -static void -sys_format(_Py_Identifier *key, FILE *fp, const char *format, va_list va) -{ - PyObject *file, *message; - PyObject *error_type, *error_value, *error_traceback; - const char *utf8; - PyThreadState *tstate = _PyThreadState_GET(); - - _PyErr_Fetch(tstate, &error_type, &error_value, &error_traceback); - file = sys_get_object_id(tstate, key); - message = PyUnicode_FromFormatV(format, va); - if (message != NULL) { - if (sys_pyfile_write_unicode(message, file) != 0) { - _PyErr_Clear(tstate); - utf8 = PyUnicode_AsUTF8(message); - if (utf8 != NULL) - fputs(utf8, fp); - } - Py_DECREF(message); - } - _PyErr_Restore(tstate, error_type, error_value, error_traceback); -} - -void -PySys_FormatStdout(const char *format, ...) -{ - va_list va; - - va_start(va, format); - sys_format(&PyId_stdout, stdout, format, va); - va_end(va); -} - -void -PySys_FormatStderr(const char *format, ...) -{ - va_list va; - - va_start(va, format); - sys_format(&PyId_stderr, stderr, format, va); - va_end(va); -} diff --git a/contrib/tools/python3/src/Python/thread.c b/contrib/tools/python3/src/Python/thread.c deleted file mode 100644 index dfe28b6bdb6..00000000000 --- a/contrib/tools/python3/src/Python/thread.c +++ /dev/null @@ -1,245 +0,0 @@ - -/* Thread package. - This is intended to be usable independently from Python. - The implementation for system foobar is in a file thread_foobar.h - which is included by this file dependent on config settings. - Stuff shared by all thread_*.h files is collected here. */ - -#include "Python.h" -#include "pycore_pystate.h" // _PyInterpreterState_GET() - -#ifndef _POSIX_THREADS -/* This means pthreads are not implemented in libc headers, hence the macro - not present in unistd.h. But they still can be implemented as an external - library (e.g. gnu pth in pthread emulation) */ -# ifdef HAVE_PTHREAD_H -# include <pthread.h> /* _POSIX_THREADS */ -# endif -#endif - -#ifndef DONT_HAVE_STDIO_H -#include <stdio.h> -#endif - -#include <stdlib.h> - -#ifndef _POSIX_THREADS - -/* Check if we're running on HP-UX and _SC_THREADS is defined. If so, then - enough of the Posix threads package is implemented to support python - threads. - - This is valid for HP-UX 11.23 running on an ia64 system. If needed, add - a check of __ia64 to verify that we're running on an ia64 system instead - of a pa-risc system. -*/ -#ifdef __hpux -#ifdef _SC_THREADS -#define _POSIX_THREADS -#endif -#endif - -#endif /* _POSIX_THREADS */ - - -#ifdef Py_DEBUG -static int thread_debug = 0; -#define dprintf(args) (void)((thread_debug & 1) && printf args) -#define d2printf(args) ((thread_debug & 8) && printf args) -#else -#define dprintf(args) -#define d2printf(args) -#endif - -static int initialized; - -static void PyThread__init_thread(void); /* Forward */ - -void -PyThread_init_thread(void) -{ -#ifdef Py_DEBUG - const char *p = Py_GETENV("PYTHONTHREADDEBUG"); - - if (p) { - if (*p) - thread_debug = atoi(p); - else - thread_debug = 1; - } -#endif /* Py_DEBUG */ - if (initialized) - return; - initialized = 1; - dprintf(("PyThread_init_thread called\n")); - PyThread__init_thread(); -} - -void -_PyThread_debug_deprecation(void) -{ -#ifdef Py_DEBUG - if (thread_debug) { - // Flush previous dprintf() logs - fflush(stdout); - if (PyErr_WarnEx(PyExc_DeprecationWarning, - "The threading debug (PYTHONTHREADDEBUG environment " - "variable) is deprecated and will be removed " - "in Python 3.12", - 0)) - { - _PyErr_WriteUnraisableMsg("at Python startup", NULL); - } - } -#endif -} - -#if defined(_POSIX_THREADS) -# define PYTHREAD_NAME "pthread" -# include "thread_pthread.h" -#elif defined(NT_THREADS) -# define PYTHREAD_NAME "nt" -# include "thread_nt.h" -#else -# error "Require native threads. See https://bugs.python.org/issue31370" -#endif - - -/* return the current thread stack size */ -size_t -PyThread_get_stacksize(void) -{ - return _PyInterpreterState_GET()->pythread_stacksize; -} - -/* Only platforms defining a THREAD_SET_STACKSIZE() macro - in thread_<platform>.h support changing the stack size. - Return 0 if stack size is valid, - -1 if stack size value is invalid, - -2 if setting stack size is not supported. */ -int -PyThread_set_stacksize(size_t size) -{ -#if defined(THREAD_SET_STACKSIZE) - return THREAD_SET_STACKSIZE(size); -#else - return -2; -#endif -} - - -/* Thread Specific Storage (TSS) API - - Cross-platform components of TSS API implementation. -*/ - -Py_tss_t * -PyThread_tss_alloc(void) -{ - Py_tss_t *new_key = (Py_tss_t *)PyMem_RawMalloc(sizeof(Py_tss_t)); - if (new_key == NULL) { - return NULL; - } - new_key->_is_initialized = 0; - return new_key; -} - -void -PyThread_tss_free(Py_tss_t *key) -{ - if (key != NULL) { - PyThread_tss_delete(key); - PyMem_RawFree((void *)key); - } -} - -int -PyThread_tss_is_created(Py_tss_t *key) -{ - assert(key != NULL); - return key->_is_initialized; -} - - -PyDoc_STRVAR(threadinfo__doc__, -"sys.thread_info\n\ -\n\ -A named tuple holding information about the thread implementation."); - -static PyStructSequence_Field threadinfo_fields[] = { - {"name", "name of the thread implementation"}, - {"lock", "name of the lock implementation"}, - {"version", "name and version of the thread library"}, - {0} -}; - -static PyStructSequence_Desc threadinfo_desc = { - "sys.thread_info", /* name */ - threadinfo__doc__, /* doc */ - threadinfo_fields, /* fields */ - 3 -}; - -static PyTypeObject ThreadInfoType; - -PyObject* -PyThread_GetInfo(void) -{ - PyObject *threadinfo, *value; - int pos = 0; -#if (defined(_POSIX_THREADS) && defined(HAVE_CONFSTR) \ - && defined(_CS_GNU_LIBPTHREAD_VERSION)) - char buffer[255]; - int len; -#endif - - if (ThreadInfoType.tp_name == 0) { - if (PyStructSequence_InitType2(&ThreadInfoType, &threadinfo_desc) < 0) - return NULL; - } - - threadinfo = PyStructSequence_New(&ThreadInfoType); - if (threadinfo == NULL) - return NULL; - - value = PyUnicode_FromString(PYTHREAD_NAME); - if (value == NULL) { - Py_DECREF(threadinfo); - return NULL; - } - PyStructSequence_SET_ITEM(threadinfo, pos++, value); - -#ifdef _POSIX_THREADS -#ifdef USE_SEMAPHORES - value = PyUnicode_FromString("semaphore"); -#else - value = PyUnicode_FromString("mutex+cond"); -#endif - if (value == NULL) { - Py_DECREF(threadinfo); - return NULL; - } -#else - Py_INCREF(Py_None); - value = Py_None; -#endif - PyStructSequence_SET_ITEM(threadinfo, pos++, value); - -#if (defined(_POSIX_THREADS) && defined(HAVE_CONFSTR) \ - && defined(_CS_GNU_LIBPTHREAD_VERSION)) - value = NULL; - len = confstr(_CS_GNU_LIBPTHREAD_VERSION, buffer, sizeof(buffer)); - if (1 < len && (size_t)len < sizeof(buffer)) { - value = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1); - if (value == NULL) - PyErr_Clear(); - } - if (value == NULL) -#endif - { - Py_INCREF(Py_None); - value = Py_None; - } - PyStructSequence_SET_ITEM(threadinfo, pos++, value); - return threadinfo; -} diff --git a/contrib/tools/python3/src/Python/thread_nt.h b/contrib/tools/python3/src/Python/thread_nt.h deleted file mode 100644 index 0ce5e94f89b..00000000000 --- a/contrib/tools/python3/src/Python/thread_nt.h +++ /dev/null @@ -1,505 +0,0 @@ -#include "pycore_interp.h" // _PyInterpreterState.pythread_stacksize - -/* This code implemented by [email protected] */ -/* Fast NonRecursiveMutex support by Yakov Markovitch, [email protected] */ -/* Eliminated some memory leaks, [email protected] */ - -#include <windows.h> -#include <limits.h> -#ifdef HAVE_PROCESS_H -#include <process.h> -#endif - -/* options */ -#ifndef _PY_USE_CV_LOCKS -#define _PY_USE_CV_LOCKS 1 /* use locks based on cond vars */ -#endif - -/* Now, define a non-recursive mutex using either condition variables - * and critical sections (fast) or using operating system mutexes - * (slow) - */ - -#if _PY_USE_CV_LOCKS - -#include "condvar.h" - -typedef struct _NRMUTEX -{ - PyMUTEX_T cs; - PyCOND_T cv; - int locked; -} NRMUTEX; -typedef NRMUTEX *PNRMUTEX; - -PNRMUTEX -AllocNonRecursiveMutex() -{ - PNRMUTEX m = (PNRMUTEX)PyMem_RawMalloc(sizeof(NRMUTEX)); - if (!m) - return NULL; - if (PyCOND_INIT(&m->cv)) - goto fail; - if (PyMUTEX_INIT(&m->cs)) { - PyCOND_FINI(&m->cv); - goto fail; - } - m->locked = 0; - return m; -fail: - PyMem_RawFree(m); - return NULL; -} - -VOID -FreeNonRecursiveMutex(PNRMUTEX mutex) -{ - if (mutex) { - PyCOND_FINI(&mutex->cv); - PyMUTEX_FINI(&mutex->cs); - PyMem_RawFree(mutex); - } -} - -DWORD -EnterNonRecursiveMutex(PNRMUTEX mutex, DWORD milliseconds) -{ - DWORD result = WAIT_OBJECT_0; - if (PyMUTEX_LOCK(&mutex->cs)) - return WAIT_FAILED; - if (milliseconds == INFINITE) { - while (mutex->locked) { - if (PyCOND_WAIT(&mutex->cv, &mutex->cs)) { - result = WAIT_FAILED; - break; - } - } - } else if (milliseconds != 0) { - /* wait at least until the target */ - _PyTime_t now = _PyTime_GetPerfCounter(); - if (now <= 0) { - Py_FatalError("_PyTime_GetPerfCounter() == 0"); - } - _PyTime_t nanoseconds = _PyTime_FromNanoseconds((_PyTime_t)milliseconds * 1000000); - _PyTime_t target = now + nanoseconds; - while (mutex->locked) { - _PyTime_t microseconds = _PyTime_AsMicroseconds(nanoseconds, _PyTime_ROUND_TIMEOUT); - if (PyCOND_TIMEDWAIT(&mutex->cv, &mutex->cs, microseconds) < 0) { - result = WAIT_FAILED; - break; - } - now = _PyTime_GetPerfCounter(); - if (target <= now) - break; - nanoseconds = target - now; - } - } - if (!mutex->locked) { - mutex->locked = 1; - result = WAIT_OBJECT_0; - } else if (result == WAIT_OBJECT_0) - result = WAIT_TIMEOUT; - /* else, it is WAIT_FAILED */ - PyMUTEX_UNLOCK(&mutex->cs); /* must ignore result here */ - return result; -} - -BOOL -LeaveNonRecursiveMutex(PNRMUTEX mutex) -{ - BOOL result; - if (PyMUTEX_LOCK(&mutex->cs)) - return FALSE; - mutex->locked = 0; - /* condvar APIs return 0 on success. We need to return TRUE on success. */ - result = !PyCOND_SIGNAL(&mutex->cv); - PyMUTEX_UNLOCK(&mutex->cs); - return result; -} - -#else /* if ! _PY_USE_CV_LOCKS */ - -/* NR-locks based on a kernel mutex */ -#define PNRMUTEX HANDLE - -PNRMUTEX -AllocNonRecursiveMutex() -{ - return CreateSemaphore(NULL, 1, 1, NULL); -} - -VOID -FreeNonRecursiveMutex(PNRMUTEX mutex) -{ - /* No in-use check */ - CloseHandle(mutex); -} - -DWORD -EnterNonRecursiveMutex(PNRMUTEX mutex, DWORD milliseconds) -{ - return WaitForSingleObjectEx(mutex, milliseconds, FALSE); -} - -BOOL -LeaveNonRecursiveMutex(PNRMUTEX mutex) -{ - return ReleaseSemaphore(mutex, 1, NULL); -} -#endif /* _PY_USE_CV_LOCKS */ - -unsigned long PyThread_get_thread_ident(void); - -#ifdef PY_HAVE_THREAD_NATIVE_ID -unsigned long PyThread_get_thread_native_id(void); -#endif - -/* - * Initialization of the C package, should not be needed. - */ -static void -PyThread__init_thread(void) -{ -} - -/* - * Thread support. - */ - -typedef struct { - void (*func)(void*); - void *arg; -} callobj; - -/* thunker to call adapt between the function type used by the system's -thread start function and the internally used one. */ -static unsigned __stdcall -bootstrap(void *call) -{ - callobj *obj = (callobj*)call; - void (*func)(void*) = obj->func; - void *arg = obj->arg; - HeapFree(GetProcessHeap(), 0, obj); - func(arg); - return 0; -} - -unsigned long -PyThread_start_new_thread(void (*func)(void *), void *arg) -{ - HANDLE hThread; - unsigned threadID; - callobj *obj; - - dprintf(("%lu: PyThread_start_new_thread called\n", - PyThread_get_thread_ident())); - if (!initialized) - PyThread_init_thread(); - - obj = (callobj*)HeapAlloc(GetProcessHeap(), 0, sizeof(*obj)); - if (!obj) - return PYTHREAD_INVALID_THREAD_ID; - obj->func = func; - obj->arg = arg; - PyThreadState *tstate = _PyThreadState_GET(); - size_t stacksize = tstate ? tstate->interp->pythread_stacksize : 0; - hThread = (HANDLE)_beginthreadex(0, - Py_SAFE_DOWNCAST(stacksize, Py_ssize_t, unsigned int), - bootstrap, obj, - 0, &threadID); - if (hThread == 0) { - /* I've seen errno == EAGAIN here, which means "there are - * too many threads". - */ - int e = errno; - dprintf(("%lu: PyThread_start_new_thread failed, errno %d\n", - PyThread_get_thread_ident(), e)); - threadID = (unsigned)-1; - HeapFree(GetProcessHeap(), 0, obj); - } - else { - dprintf(("%lu: PyThread_start_new_thread succeeded: %p\n", - PyThread_get_thread_ident(), (void*)hThread)); - CloseHandle(hThread); - } - return threadID; -} - -/* - * Return the thread Id instead of a handle. The Id is said to uniquely identify the - * thread in the system - */ -unsigned long -PyThread_get_thread_ident(void) -{ - if (!initialized) - PyThread_init_thread(); - - return GetCurrentThreadId(); -} - -#ifdef PY_HAVE_THREAD_NATIVE_ID -/* - * Return the native Thread ID (TID) of the calling thread. - * The native ID of a thread is valid and guaranteed to be unique system-wide - * from the time the thread is created until the thread has been terminated. - */ -unsigned long -PyThread_get_thread_native_id(void) -{ - if (!initialized) { - PyThread_init_thread(); - } - - DWORD native_id; - native_id = GetCurrentThreadId(); - return (unsigned long) native_id; -} -#endif - -void _Py_NO_RETURN -PyThread_exit_thread(void) -{ - dprintf(("%lu: PyThread_exit_thread called\n", PyThread_get_thread_ident())); - if (!initialized) - exit(0); - _endthreadex(0); -} - -/* - * Lock support. It has to be implemented as semaphores. - * I [Dag] tried to implement it with mutex but I could find a way to - * tell whether a thread already own the lock or not. - */ -PyThread_type_lock -PyThread_allocate_lock(void) -{ - PNRMUTEX aLock; - - dprintf(("PyThread_allocate_lock called\n")); - if (!initialized) - PyThread_init_thread(); - - aLock = AllocNonRecursiveMutex() ; - - dprintf(("%lu: PyThread_allocate_lock() -> %p\n", PyThread_get_thread_ident(), aLock)); - - return (PyThread_type_lock) aLock; -} - -void -PyThread_free_lock(PyThread_type_lock aLock) -{ - dprintf(("%lu: PyThread_free_lock(%p) called\n", PyThread_get_thread_ident(),aLock)); - - FreeNonRecursiveMutex(aLock) ; -} - -/* - * Return 1 on success if the lock was acquired - * - * and 0 if the lock was not acquired. This means a 0 is returned - * if the lock has already been acquired by this thread! - */ -PyLockStatus -PyThread_acquire_lock_timed(PyThread_type_lock aLock, - PY_TIMEOUT_T microseconds, int intr_flag) -{ - /* Fow now, intr_flag does nothing on Windows, and lock acquires are - * uninterruptible. */ - PyLockStatus success; - PY_TIMEOUT_T milliseconds; - - if (microseconds >= 0) { - milliseconds = microseconds / 1000; - if (microseconds % 1000 > 0) - ++milliseconds; - if (milliseconds > PY_DWORD_MAX) { - Py_FatalError("Timeout larger than PY_TIMEOUT_MAX"); - } - } - else { - milliseconds = INFINITE; - } - - dprintf(("%lu: PyThread_acquire_lock_timed(%p, %lld) called\n", - PyThread_get_thread_ident(), aLock, microseconds)); - - if (aLock && EnterNonRecursiveMutex((PNRMUTEX)aLock, - (DWORD)milliseconds) == WAIT_OBJECT_0) { - success = PY_LOCK_ACQUIRED; - } - else { - success = PY_LOCK_FAILURE; - } - - dprintf(("%lu: PyThread_acquire_lock(%p, %lld) -> %d\n", - PyThread_get_thread_ident(), aLock, microseconds, success)); - - return success; -} -int -PyThread_acquire_lock(PyThread_type_lock aLock, int waitflag) -{ - return PyThread_acquire_lock_timed(aLock, waitflag ? -1 : 0, 0); -} - -void -PyThread_release_lock(PyThread_type_lock aLock) -{ - dprintf(("%lu: PyThread_release_lock(%p) called\n", PyThread_get_thread_ident(),aLock)); - - if (!(aLock && LeaveNonRecursiveMutex((PNRMUTEX) aLock))) - dprintf(("%lu: Could not PyThread_release_lock(%p) error: %ld\n", PyThread_get_thread_ident(), aLock, GetLastError())); -} - -/* minimum/maximum thread stack sizes supported */ -#define THREAD_MIN_STACKSIZE 0x8000 /* 32 KiB */ -#define THREAD_MAX_STACKSIZE 0x10000000 /* 256 MiB */ - -/* set the thread stack size. - * Return 0 if size is valid, -1 otherwise. - */ -static int -_pythread_nt_set_stacksize(size_t size) -{ - /* set to default */ - if (size == 0) { - _PyInterpreterState_GET()->pythread_stacksize = 0; - return 0; - } - - /* valid range? */ - if (size >= THREAD_MIN_STACKSIZE && size < THREAD_MAX_STACKSIZE) { - _PyInterpreterState_GET()->pythread_stacksize = size; - return 0; - } - - return -1; -} - -#define THREAD_SET_STACKSIZE(x) _pythread_nt_set_stacksize(x) - - -/* Thread Local Storage (TLS) API - - This API is DEPRECATED since Python 3.7. See PEP 539 for details. -*/ - -int -PyThread_create_key(void) -{ - DWORD result = TlsAlloc(); - if (result == TLS_OUT_OF_INDEXES) - return -1; - return (int)result; -} - -void -PyThread_delete_key(int key) -{ - TlsFree(key); -} - -int -PyThread_set_key_value(int key, void *value) -{ - BOOL ok = TlsSetValue(key, value); - return ok ? 0 : -1; -} - -void * -PyThread_get_key_value(int key) -{ - /* because TLS is used in the Py_END_ALLOW_THREAD macro, - * it is necessary to preserve the windows error state, because - * it is assumed to be preserved across the call to the macro. - * Ideally, the macro should be fixed, but it is simpler to - * do it here. - */ - DWORD error = GetLastError(); - void *result = TlsGetValue(key); - SetLastError(error); - return result; -} - -void -PyThread_delete_key_value(int key) -{ - /* NULL is used as "key missing", and it is also the default - * given by TlsGetValue() if nothing has been set yet. - */ - TlsSetValue(key, NULL); -} - - -/* reinitialization of TLS is not necessary after fork when using - * the native TLS functions. And forking isn't supported on Windows either. - */ -void -PyThread_ReInitTLS(void) -{ -} - - -/* Thread Specific Storage (TSS) API - - Platform-specific components of TSS API implementation. -*/ - -int -PyThread_tss_create(Py_tss_t *key) -{ - assert(key != NULL); - /* If the key has been created, function is silently skipped. */ - if (key->_is_initialized) { - return 0; - } - - DWORD result = TlsAlloc(); - if (result == TLS_OUT_OF_INDEXES) { - return -1; - } - /* In Windows, platform-specific key type is DWORD. */ - key->_key = result; - key->_is_initialized = 1; - return 0; -} - -void -PyThread_tss_delete(Py_tss_t *key) -{ - assert(key != NULL); - /* If the key has not been created, function is silently skipped. */ - if (!key->_is_initialized) { - return; - } - - TlsFree(key->_key); - key->_key = TLS_OUT_OF_INDEXES; - key->_is_initialized = 0; -} - -int -PyThread_tss_set(Py_tss_t *key, void *value) -{ - assert(key != NULL); - BOOL ok = TlsSetValue(key->_key, value); - return ok ? 0 : -1; -} - -void * -PyThread_tss_get(Py_tss_t *key) -{ - assert(key != NULL); - /* because TSS is used in the Py_END_ALLOW_THREAD macro, - * it is necessary to preserve the windows error state, because - * it is assumed to be preserved across the call to the macro. - * Ideally, the macro should be fixed, but it is simpler to - * do it here. - */ - DWORD error = GetLastError(); - void *result = TlsGetValue(key->_key); - SetLastError(error); - return result; -} diff --git a/contrib/tools/python3/src/Python/thread_pthread.h b/contrib/tools/python3/src/Python/thread_pthread.h deleted file mode 100644 index 35b9810aa37..00000000000 --- a/contrib/tools/python3/src/Python/thread_pthread.h +++ /dev/null @@ -1,929 +0,0 @@ -#include "pycore_interp.h" // _PyInterpreterState.pythread_stacksize - -/* Posix threads interface */ - -#include <stdlib.h> -#include <string.h> -#if defined(__APPLE__) || defined(HAVE_PTHREAD_DESTRUCTOR) -#define destructor xxdestructor -#endif -#include <pthread.h> -#if defined(__APPLE__) || defined(HAVE_PTHREAD_DESTRUCTOR) -#undef destructor -#endif -#include <signal.h> - -#if defined(__linux__) -# include <sys/syscall.h> /* syscall(SYS_gettid) */ -#elif defined(__FreeBSD__) -# include <pthread_np.h> /* pthread_getthreadid_np() */ -#elif defined(__OpenBSD__) -# include <unistd.h> /* getthrid() */ -#elif defined(_AIX) -# include <sys/thread.h> /* thread_self() */ -#elif defined(__NetBSD__) -# include <lwp.h> /* _lwp_self() */ -#endif - -/* The POSIX spec requires that use of pthread_attr_setstacksize - be conditional on _POSIX_THREAD_ATTR_STACKSIZE being defined. */ -#ifdef _POSIX_THREAD_ATTR_STACKSIZE -#ifndef THREAD_STACK_SIZE -#define THREAD_STACK_SIZE 0 /* use default stack size */ -#endif - -/* The default stack size for new threads on BSD is small enough that - * we'll get hard crashes instead of 'maximum recursion depth exceeded' - * exceptions. - * - * The default stack size below is the empirically determined minimal stack - * sizes where a simple recursive function doesn't cause a hard crash. - * - * For macOS the value of THREAD_STACK_SIZE is determined in configure.ac - * as it also depends on the other configure options like chosen sanitizer - * runtimes. - */ -#if defined(__FreeBSD__) && defined(THREAD_STACK_SIZE) && THREAD_STACK_SIZE == 0 -#undef THREAD_STACK_SIZE -#define THREAD_STACK_SIZE 0x400000 -#endif -#if defined(_AIX) && defined(THREAD_STACK_SIZE) && THREAD_STACK_SIZE == 0 -#undef THREAD_STACK_SIZE -#define THREAD_STACK_SIZE 0x200000 -#endif -/* bpo-38852: test_threading.test_recursion_limit() checks that 1000 recursive - Python calls (default recursion limit) doesn't crash, but raise a regular - RecursionError exception. In debug mode, Python function calls allocates - more memory on the stack, so use a stack of 8 MiB. */ -#if defined(__ANDROID__) && defined(THREAD_STACK_SIZE) && THREAD_STACK_SIZE == 0 -# ifdef Py_DEBUG -# undef THREAD_STACK_SIZE -# define THREAD_STACK_SIZE 0x800000 -# endif -#endif -#if defined(__VXWORKS__) && defined(THREAD_STACK_SIZE) && THREAD_STACK_SIZE == 0 -#undef THREAD_STACK_SIZE -#define THREAD_STACK_SIZE 0x100000 -#endif -/* for safety, ensure a viable minimum stacksize */ -#define THREAD_STACK_MIN 0x8000 /* 32 KiB */ -#else /* !_POSIX_THREAD_ATTR_STACKSIZE */ -#ifdef THREAD_STACK_SIZE -#error "THREAD_STACK_SIZE defined but _POSIX_THREAD_ATTR_STACKSIZE undefined" -#endif -#endif - -/* The POSIX spec says that implementations supporting the sem_* - family of functions must indicate this by defining - _POSIX_SEMAPHORES. */ -#ifdef _POSIX_SEMAPHORES -/* On FreeBSD 4.x, _POSIX_SEMAPHORES is defined empty, so - we need to add 0 to make it work there as well. */ -#if (_POSIX_SEMAPHORES+0) == -1 -#define HAVE_BROKEN_POSIX_SEMAPHORES -#else -#include <semaphore.h> -#include <errno.h> -#endif -#endif - - -/* Whether or not to use semaphores directly rather than emulating them with - * mutexes and condition variables: - */ -#if (defined(_POSIX_SEMAPHORES) && !defined(HAVE_BROKEN_POSIX_SEMAPHORES) && \ - (defined(HAVE_SEM_TIMEDWAIT) || defined(HAVE_SEM_CLOCKWAIT))) -# define USE_SEMAPHORES -#else -# undef USE_SEMAPHORES -#endif - -#if defined(HAVE_PTHREAD_CONDATTR_SETCLOCK) && defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC) -// monotonic is supported statically. It doesn't mean it works on runtime. -#define CONDATTR_MONOTONIC -#endif - - -/* On platforms that don't use standard POSIX threads pthread_sigmask() - * isn't present. DEC threads uses sigprocmask() instead as do most - * other UNIX International compliant systems that don't have the full - * pthread implementation. - */ -#if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK) -# define SET_THREAD_SIGMASK pthread_sigmask -#else -# define SET_THREAD_SIGMASK sigprocmask -#endif - - -#define MICROSECONDS_TO_TIMESPEC(microseconds, ts) \ -do { \ - struct timeval tv; \ - gettimeofday(&tv, NULL); \ - tv.tv_usec += microseconds % 1000000; \ - tv.tv_sec += microseconds / 1000000; \ - tv.tv_sec += tv.tv_usec / 1000000; \ - tv.tv_usec %= 1000000; \ - ts.tv_sec = tv.tv_sec; \ - ts.tv_nsec = tv.tv_usec * 1000; \ -} while(0) - -#if defined(CONDATTR_MONOTONIC) || defined(HAVE_SEM_CLOCKWAIT) -static void -monotonic_abs_timeout(long long us, struct timespec *abs) -{ - clock_gettime(CLOCK_MONOTONIC, abs); - abs->tv_sec += us / 1000000; - abs->tv_nsec += (us % 1000000) * 1000; - abs->tv_sec += abs->tv_nsec / 1000000000; - abs->tv_nsec %= 1000000000; -} -#endif - - -/* - * pthread_cond support - */ - -// NULL when pthread_condattr_setclock(CLOCK_MONOTONIC) is not supported. -static pthread_condattr_t *condattr_monotonic = NULL; - -static void -init_condattr(void) -{ -#ifdef CONDATTR_MONOTONIC - static pthread_condattr_t ca; - pthread_condattr_init(&ca); - if (pthread_condattr_setclock(&ca, CLOCK_MONOTONIC) == 0) { - condattr_monotonic = &ca; // Use monotonic clock - } -#endif -} - -int -_PyThread_cond_init(PyCOND_T *cond) -{ - return pthread_cond_init(cond, condattr_monotonic); -} - - -void -_PyThread_cond_after(long long us, struct timespec *abs) -{ -#ifdef CONDATTR_MONOTONIC - if (condattr_monotonic) { - monotonic_abs_timeout(us, abs); - return; - } -#endif - - struct timespec ts; - MICROSECONDS_TO_TIMESPEC(us, ts); - *abs = ts; -} - - -/* A pthread mutex isn't sufficient to model the Python lock type - * because, according to Draft 5 of the docs (P1003.4a/D5), both of the - * following are undefined: - * -> a thread tries to lock a mutex it already has locked - * -> a thread tries to unlock a mutex locked by a different thread - * pthread mutexes are designed for serializing threads over short pieces - * of code anyway, so wouldn't be an appropriate implementation of - * Python's locks regardless. - * - * The pthread_lock struct implements a Python lock as a "locked?" bit - * and a <condition, mutex> pair. In general, if the bit can be acquired - * instantly, it is, else the pair is used to block the thread until the - * bit is cleared. 9 May 1994 [email protected] - */ - -typedef struct { - char locked; /* 0=unlocked, 1=locked */ - /* a <cond, mutex> pair to handle an acquire of a locked lock */ - pthread_cond_t lock_released; - pthread_mutex_t mut; -} pthread_lock; - -#define CHECK_STATUS(name) if (status != 0) { perror(name); error = 1; } -#define CHECK_STATUS_PTHREAD(name) if (status != 0) { fprintf(stderr, \ - "%s: %s\n", name, strerror(status)); error = 1; } - -/* - * Initialization. - */ -static void -PyThread__init_thread(void) -{ -#if defined(_AIX) && defined(__GNUC__) - extern void pthread_init(void); - pthread_init(); -#endif - init_condattr(); -} - -/* - * Thread support. - */ - -/* bpo-33015: pythread_callback struct and pythread_wrapper() cast - "void func(void *)" to "void* func(void *)": always return NULL. - - PyThread_start_new_thread() uses "void func(void *)" type, whereas - pthread_create() requires a void* return value. */ -typedef struct { - void (*func) (void *); - void *arg; -} pythread_callback; - -static void * -pythread_wrapper(void *arg) -{ - /* copy func and func_arg and free the temporary structure */ - pythread_callback *callback = arg; - void (*func)(void *) = callback->func; - void *func_arg = callback->arg; - PyMem_RawFree(arg); - - func(func_arg); - return NULL; -} - -unsigned long -PyThread_start_new_thread(void (*func)(void *), void *arg) -{ - pthread_t th; - int status; -#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED) - pthread_attr_t attrs; -#endif -#if defined(THREAD_STACK_SIZE) - size_t tss; -#endif - - dprintf(("PyThread_start_new_thread called\n")); - if (!initialized) - PyThread_init_thread(); - -#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED) - if (pthread_attr_init(&attrs) != 0) - return PYTHREAD_INVALID_THREAD_ID; -#endif -#if defined(THREAD_STACK_SIZE) - PyThreadState *tstate = _PyThreadState_GET(); - size_t stacksize = tstate ? tstate->interp->pythread_stacksize : 0; - tss = (stacksize != 0) ? stacksize : THREAD_STACK_SIZE; - if (tss != 0) { - if (pthread_attr_setstacksize(&attrs, tss) != 0) { - pthread_attr_destroy(&attrs); - return PYTHREAD_INVALID_THREAD_ID; - } - } -#endif -#if defined(PTHREAD_SYSTEM_SCHED_SUPPORTED) - pthread_attr_setscope(&attrs, PTHREAD_SCOPE_SYSTEM); -#endif - - pythread_callback *callback = PyMem_RawMalloc(sizeof(pythread_callback)); - - if (callback == NULL) { - return PYTHREAD_INVALID_THREAD_ID; - } - - callback->func = func; - callback->arg = arg; - - status = pthread_create(&th, -#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED) - &attrs, -#else - (pthread_attr_t*)NULL, -#endif - pythread_wrapper, callback); - -#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED) - pthread_attr_destroy(&attrs); -#endif - - if (status != 0) { - PyMem_RawFree(callback); - return PYTHREAD_INVALID_THREAD_ID; - } - - pthread_detach(th); - -#if SIZEOF_PTHREAD_T <= SIZEOF_LONG - return (unsigned long) th; -#else - return (unsigned long) *(unsigned long *) &th; -#endif -} - -/* XXX This implementation is considered (to quote Tim Peters) "inherently - hosed" because: - - It does not guarantee the promise that a non-zero integer is returned. - - The cast to unsigned long is inherently unsafe. - - It is not clear that the 'volatile' (for AIX?) are any longer necessary. -*/ -unsigned long -PyThread_get_thread_ident(void) -{ - volatile pthread_t threadid; - if (!initialized) - PyThread_init_thread(); - threadid = pthread_self(); - return (unsigned long) threadid; -} - -#ifdef PY_HAVE_THREAD_NATIVE_ID -unsigned long -PyThread_get_thread_native_id(void) -{ - if (!initialized) - PyThread_init_thread(); -#ifdef __APPLE__ - uint64_t native_id; - (void) pthread_threadid_np(NULL, &native_id); -#elif defined(__linux__) - pid_t native_id; - native_id = syscall(SYS_gettid); -#elif defined(__FreeBSD__) - int native_id; - native_id = pthread_getthreadid_np(); -#elif defined(__OpenBSD__) - pid_t native_id; - native_id = getthrid(); -#elif defined(_AIX) - tid_t native_id; - native_id = thread_self(); -#elif defined(__NetBSD__) - lwpid_t native_id; - native_id = _lwp_self(); -#endif - return (unsigned long) native_id; -} -#endif - -void _Py_NO_RETURN -PyThread_exit_thread(void) -{ - dprintf(("PyThread_exit_thread called\n")); - if (!initialized) - exit(0); - pthread_exit(0); -} - -#ifdef USE_SEMAPHORES - -/* - * Lock support. - */ - -PyThread_type_lock -PyThread_allocate_lock(void) -{ - sem_t *lock; - int status, error = 0; - - dprintf(("PyThread_allocate_lock called\n")); - if (!initialized) - PyThread_init_thread(); - - lock = (sem_t *)PyMem_RawMalloc(sizeof(sem_t)); - - if (lock) { - status = sem_init(lock,0,1); - CHECK_STATUS("sem_init"); - - if (error) { - PyMem_RawFree((void *)lock); - lock = NULL; - } - } - - dprintf(("PyThread_allocate_lock() -> %p\n", (void *)lock)); - return (PyThread_type_lock)lock; -} - -void -PyThread_free_lock(PyThread_type_lock lock) -{ - sem_t *thelock = (sem_t *)lock; - int status, error = 0; - - (void) error; /* silence unused-but-set-variable warning */ - dprintf(("PyThread_free_lock(%p) called\n", lock)); - - if (!thelock) - return; - - status = sem_destroy(thelock); - CHECK_STATUS("sem_destroy"); - - PyMem_RawFree((void *)thelock); -} - -/* - * As of February 2002, Cygwin thread implementations mistakenly report error - * codes in the return value of the sem_ calls (like the pthread_ functions). - * Correct implementations return -1 and put the code in errno. This supports - * either. - */ -static int -fix_status(int status) -{ - return (status == -1) ? errno : status; -} - -PyLockStatus -PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds, - int intr_flag) -{ - PyLockStatus success; - sem_t *thelock = (sem_t *)lock; - int status, error = 0; - struct timespec ts; -#ifndef HAVE_SEM_CLOCKWAIT - _PyTime_t deadline = 0; -#endif - - (void) error; /* silence unused-but-set-variable warning */ - dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) called\n", - lock, microseconds, intr_flag)); - - if (microseconds > PY_TIMEOUT_MAX) { - Py_FatalError("Timeout larger than PY_TIMEOUT_MAX"); - } - - if (microseconds > 0) { -#ifdef HAVE_SEM_CLOCKWAIT - monotonic_abs_timeout(microseconds, &ts); -#else - MICROSECONDS_TO_TIMESPEC(microseconds, ts); - - if (!intr_flag) { - /* cannot overflow thanks to (microseconds > PY_TIMEOUT_MAX) - check done above */ - _PyTime_t timeout = _PyTime_FromNanoseconds(microseconds * 1000); - deadline = _PyTime_GetMonotonicClock() + timeout; - } -#endif - } - - while (1) { - if (microseconds > 0) { -#ifdef HAVE_SEM_CLOCKWAIT - status = fix_status(sem_clockwait(thelock, CLOCK_MONOTONIC, - &ts)); -#else - status = fix_status(sem_timedwait(thelock, &ts)); -#endif - } - else if (microseconds == 0) { - status = fix_status(sem_trywait(thelock)); - } - else { - status = fix_status(sem_wait(thelock)); - } - - /* Retry if interrupted by a signal, unless the caller wants to be - notified. */ - if (intr_flag || status != EINTR) { - break; - } - - // sem_clockwait() uses an absolute timeout, there is no need - // to recompute the relative timeout. -#ifndef HAVE_SEM_CLOCKWAIT - if (microseconds > 0) { - /* wait interrupted by a signal (EINTR): recompute the timeout */ - _PyTime_t dt = deadline - _PyTime_GetMonotonicClock(); - if (dt < 0) { - status = ETIMEDOUT; - break; - } - else if (dt > 0) { - _PyTime_t realtime_deadline = _PyTime_GetSystemClock() + dt; - if (_PyTime_AsTimespec(realtime_deadline, &ts) < 0) { - /* Cannot occur thanks to (microseconds > PY_TIMEOUT_MAX) - check done above */ - Py_UNREACHABLE(); - } - /* no need to update microseconds value, the code only care - if (microseconds > 0 or (microseconds == 0). */ - } - else { - microseconds = 0; - } - } -#endif - } - - /* Don't check the status if we're stopping because of an interrupt. */ - if (!(intr_flag && status == EINTR)) { - if (microseconds > 0) { - if (status != ETIMEDOUT) { -#ifdef HAVE_SEM_CLOCKWAIT - CHECK_STATUS("sem_clockwait"); -#else - CHECK_STATUS("sem_timedwait"); -#endif - } - } - else if (microseconds == 0) { - if (status != EAGAIN) - CHECK_STATUS("sem_trywait"); - } - else { - CHECK_STATUS("sem_wait"); - } - } - - if (status == 0) { - success = PY_LOCK_ACQUIRED; - } else if (intr_flag && status == EINTR) { - success = PY_LOCK_INTR; - } else { - success = PY_LOCK_FAILURE; - } - - dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) -> %d\n", - lock, microseconds, intr_flag, success)); - return success; -} - -void -PyThread_release_lock(PyThread_type_lock lock) -{ - sem_t *thelock = (sem_t *)lock; - int status, error = 0; - - (void) error; /* silence unused-but-set-variable warning */ - dprintf(("PyThread_release_lock(%p) called\n", lock)); - - status = sem_post(thelock); - CHECK_STATUS("sem_post"); -} - -#else /* USE_SEMAPHORES */ - -/* - * Lock support. - */ -PyThread_type_lock -PyThread_allocate_lock(void) -{ - pthread_lock *lock; - int status, error = 0; - - dprintf(("PyThread_allocate_lock called\n")); - if (!initialized) - PyThread_init_thread(); - - lock = (pthread_lock *) PyMem_RawCalloc(1, sizeof(pthread_lock)); - if (lock) { - lock->locked = 0; - - status = pthread_mutex_init(&lock->mut, NULL); - CHECK_STATUS_PTHREAD("pthread_mutex_init"); - /* Mark the pthread mutex underlying a Python mutex as - pure happens-before. We can't simply mark the - Python-level mutex as a mutex because it can be - acquired and released in different threads, which - will cause errors. */ - _Py_ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(&lock->mut); - - status = _PyThread_cond_init(&lock->lock_released); - CHECK_STATUS_PTHREAD("pthread_cond_init"); - - if (error) { - PyMem_RawFree((void *)lock); - lock = 0; - } - } - - dprintf(("PyThread_allocate_lock() -> %p\n", (void *)lock)); - return (PyThread_type_lock) lock; -} - -void -PyThread_free_lock(PyThread_type_lock lock) -{ - pthread_lock *thelock = (pthread_lock *)lock; - int status, error = 0; - - (void) error; /* silence unused-but-set-variable warning */ - dprintf(("PyThread_free_lock(%p) called\n", lock)); - - /* some pthread-like implementations tie the mutex to the cond - * and must have the cond destroyed first. - */ - status = pthread_cond_destroy( &thelock->lock_released ); - CHECK_STATUS_PTHREAD("pthread_cond_destroy"); - - status = pthread_mutex_destroy( &thelock->mut ); - CHECK_STATUS_PTHREAD("pthread_mutex_destroy"); - - PyMem_RawFree((void *)thelock); -} - -PyLockStatus -PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds, - int intr_flag) -{ - PyLockStatus success = PY_LOCK_FAILURE; - pthread_lock *thelock = (pthread_lock *)lock; - int status, error = 0; - - dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) called\n", - lock, microseconds, intr_flag)); - - if (microseconds == 0) { - status = pthread_mutex_trylock( &thelock->mut ); - if (status != EBUSY) - CHECK_STATUS_PTHREAD("pthread_mutex_trylock[1]"); - } - else { - status = pthread_mutex_lock( &thelock->mut ); - CHECK_STATUS_PTHREAD("pthread_mutex_lock[1]"); - } - if (status == 0) { - if (thelock->locked == 0) { - success = PY_LOCK_ACQUIRED; - } - else if (microseconds != 0) { - struct timespec abs; - if (microseconds > 0) { - _PyThread_cond_after(microseconds, &abs); - } - /* continue trying until we get the lock */ - - /* mut must be locked by me -- part of the condition - * protocol */ - while (success == PY_LOCK_FAILURE) { - if (microseconds > 0) { - status = pthread_cond_timedwait( - &thelock->lock_released, - &thelock->mut, &abs); - if (status == 1) { - break; - } - if (status == ETIMEDOUT) - break; - CHECK_STATUS_PTHREAD("pthread_cond_timedwait"); - } - else { - status = pthread_cond_wait( - &thelock->lock_released, - &thelock->mut); - CHECK_STATUS_PTHREAD("pthread_cond_wait"); - } - - if (intr_flag && status == 0 && thelock->locked) { - /* We were woken up, but didn't get the lock. We probably received - * a signal. Return PY_LOCK_INTR to allow the caller to handle - * it and retry. */ - success = PY_LOCK_INTR; - break; - } - else if (status == 0 && !thelock->locked) { - success = PY_LOCK_ACQUIRED; - } - } - } - if (success == PY_LOCK_ACQUIRED) thelock->locked = 1; - status = pthread_mutex_unlock( &thelock->mut ); - CHECK_STATUS_PTHREAD("pthread_mutex_unlock[1]"); - } - - if (error) success = PY_LOCK_FAILURE; - dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) -> %d\n", - lock, microseconds, intr_flag, success)); - return success; -} - -void -PyThread_release_lock(PyThread_type_lock lock) -{ - pthread_lock *thelock = (pthread_lock *)lock; - int status, error = 0; - - (void) error; /* silence unused-but-set-variable warning */ - dprintf(("PyThread_release_lock(%p) called\n", lock)); - - status = pthread_mutex_lock( &thelock->mut ); - CHECK_STATUS_PTHREAD("pthread_mutex_lock[3]"); - - thelock->locked = 0; - - /* wake up someone (anyone, if any) waiting on the lock */ - status = pthread_cond_signal( &thelock->lock_released ); - CHECK_STATUS_PTHREAD("pthread_cond_signal"); - - status = pthread_mutex_unlock( &thelock->mut ); - CHECK_STATUS_PTHREAD("pthread_mutex_unlock[3]"); -} - -#endif /* USE_SEMAPHORES */ - -int -_PyThread_at_fork_reinit(PyThread_type_lock *lock) -{ - PyThread_type_lock new_lock = PyThread_allocate_lock(); - if (new_lock == NULL) { - return -1; - } - - /* bpo-6721, bpo-40089: The old lock can be in an inconsistent state. - fork() can be called in the middle of an operation on the lock done by - another thread. So don't call PyThread_free_lock(*lock). - - Leak memory on purpose. Don't release the memory either since the - address of a mutex is relevant. Putting two mutexes at the same address - can lead to problems. */ - - *lock = new_lock; - return 0; -} - -int -PyThread_acquire_lock(PyThread_type_lock lock, int waitflag) -{ - return PyThread_acquire_lock_timed(lock, waitflag ? -1 : 0, /*intr_flag=*/0); -} - -/* set the thread stack size. - * Return 0 if size is valid, -1 if size is invalid, - * -2 if setting stack size is not supported. - */ -static int -_pythread_pthread_set_stacksize(size_t size) -{ -#if defined(THREAD_STACK_SIZE) - pthread_attr_t attrs; - size_t tss_min; - int rc = 0; -#endif - - /* set to default */ - if (size == 0) { - _PyInterpreterState_GET()->pythread_stacksize = 0; - return 0; - } - -#if defined(THREAD_STACK_SIZE) -#if defined(PTHREAD_STACK_MIN) - tss_min = PTHREAD_STACK_MIN > THREAD_STACK_MIN ? PTHREAD_STACK_MIN - : THREAD_STACK_MIN; -#else - tss_min = THREAD_STACK_MIN; -#endif - if (size >= tss_min) { - /* validate stack size by setting thread attribute */ - if (pthread_attr_init(&attrs) == 0) { - rc = pthread_attr_setstacksize(&attrs, size); - pthread_attr_destroy(&attrs); - if (rc == 0) { - _PyInterpreterState_GET()->pythread_stacksize = size; - return 0; - } - } - } - return -1; -#else - return -2; -#endif -} - -#define THREAD_SET_STACKSIZE(x) _pythread_pthread_set_stacksize(x) - - -/* Thread Local Storage (TLS) API - - This API is DEPRECATED since Python 3.7. See PEP 539 for details. -*/ - -/* Issue #25658: On platforms where native TLS key is defined in a way that - cannot be safely cast to int, PyThread_create_key returns immediately a - failure status and other TLS functions all are no-ops. This indicates - clearly that the old API is not supported on platforms where it cannot be - used reliably, and that no effort will be made to add such support. - - Note: PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT will be unnecessary after - removing this API. -*/ - -int -PyThread_create_key(void) -{ -#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT - pthread_key_t key; - int fail = pthread_key_create(&key, NULL); - if (fail) - return -1; - if (key > INT_MAX) { - /* Issue #22206: handle integer overflow */ - pthread_key_delete(key); - errno = ENOMEM; - return -1; - } - return (int)key; -#else - return -1; /* never return valid key value. */ -#endif -} - -void -PyThread_delete_key(int key) -{ -#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT - pthread_key_delete(key); -#endif -} - -void -PyThread_delete_key_value(int key) -{ -#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT - pthread_setspecific(key, NULL); -#endif -} - -int -PyThread_set_key_value(int key, void *value) -{ -#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT - int fail = pthread_setspecific(key, value); - return fail ? -1 : 0; -#else - return -1; -#endif -} - -void * -PyThread_get_key_value(int key) -{ -#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT - return pthread_getspecific(key); -#else - return NULL; -#endif -} - - -void -PyThread_ReInitTLS(void) -{ -} - - -/* Thread Specific Storage (TSS) API - - Platform-specific components of TSS API implementation. -*/ - -int -PyThread_tss_create(Py_tss_t *key) -{ - assert(key != NULL); - /* If the key has been created, function is silently skipped. */ - if (key->_is_initialized) { - return 0; - } - - int fail = pthread_key_create(&(key->_key), NULL); - if (fail) { - return -1; - } - key->_is_initialized = 1; - return 0; -} - -void -PyThread_tss_delete(Py_tss_t *key) -{ - assert(key != NULL); - /* If the key has not been created, function is silently skipped. */ - if (!key->_is_initialized) { - return; - } - - pthread_key_delete(key->_key); - /* pthread has not provided the defined invalid value for the key. */ - key->_is_initialized = 0; -} - -int -PyThread_tss_set(Py_tss_t *key, void *value) -{ - assert(key != NULL); - int fail = pthread_setspecific(key->_key, value); - return fail ? -1 : 0; -} - -void * -PyThread_tss_get(Py_tss_t *key) -{ - assert(key != NULL); - return pthread_getspecific(key->_key); -} diff --git a/contrib/tools/python3/src/Python/traceback.c b/contrib/tools/python3/src/Python/traceback.c deleted file mode 100644 index 7d6f7f435a6..00000000000 --- a/contrib/tools/python3/src/Python/traceback.c +++ /dev/null @@ -1,951 +0,0 @@ - -/* Traceback implementation */ - -#include "Python.h" - -#include "code.h" -#include "pycore_interp.h" // PyInterpreterState.gc -#include "frameobject.h" // PyFrame_GetBack() -#include "structmember.h" // PyMemberDef -#include "osdefs.h" // SEP -#ifdef HAVE_FCNTL_H -#include <fcntl.h> -#endif - -#define OFF(x) offsetof(PyTracebackObject, x) - -#define PUTS(fd, str) _Py_write_noraise(fd, str, (int)strlen(str)) -#define MAX_STRING_LENGTH 500 -#define MAX_FRAME_DEPTH 100 -#define MAX_NTHREADS 100 - -/* Function from Parser/tokenizer.c */ -extern char * PyTokenizer_FindEncodingFilename(int, PyObject *); - -_Py_IDENTIFIER(TextIOWrapper); -_Py_IDENTIFIER(close); -_Py_IDENTIFIER(open); -_Py_IDENTIFIER(path); - -/*[clinic input] -class TracebackType "PyTracebackObject *" "&PyTraceback_Type" -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=928fa06c10151120]*/ - -#include "clinic/traceback.c.h" - -static PyObject * -tb_create_raw(PyTracebackObject *next, PyFrameObject *frame, int lasti, - int lineno) -{ - PyTracebackObject *tb; - if ((next != NULL && !PyTraceBack_Check(next)) || - frame == NULL || !PyFrame_Check(frame)) { - PyErr_BadInternalCall(); - return NULL; - } - tb = PyObject_GC_New(PyTracebackObject, &PyTraceBack_Type); - if (tb != NULL) { - Py_XINCREF(next); - tb->tb_next = next; - Py_XINCREF(frame); - tb->tb_frame = frame; - tb->tb_lasti = lasti; - tb->tb_lineno = lineno; - PyObject_GC_Track(tb); - } - return (PyObject *)tb; -} - -/*[clinic input] -@classmethod -TracebackType.__new__ as tb_new - - tb_next: object - tb_frame: object(type='PyFrameObject *', subclass_of='&PyFrame_Type') - tb_lasti: int - tb_lineno: int - -Create a new traceback object. -[clinic start generated code]*/ - -static PyObject * -tb_new_impl(PyTypeObject *type, PyObject *tb_next, PyFrameObject *tb_frame, - int tb_lasti, int tb_lineno) -/*[clinic end generated code: output=fa077debd72d861a input=01cbe8ec8783fca7]*/ -{ - if (tb_next == Py_None) { - tb_next = NULL; - } else if (!PyTraceBack_Check(tb_next)) { - return PyErr_Format(PyExc_TypeError, - "expected traceback object or None, got '%s'", - Py_TYPE(tb_next)->tp_name); - } - - return tb_create_raw((PyTracebackObject *)tb_next, tb_frame, tb_lasti, - tb_lineno); -} - -static PyObject * -tb_dir(PyTracebackObject *self, PyObject *Py_UNUSED(ignored)) -{ - return Py_BuildValue("[ssss]", "tb_frame", "tb_next", - "tb_lasti", "tb_lineno"); -} - -static PyObject * -tb_next_get(PyTracebackObject *self, void *Py_UNUSED(_)) -{ - PyObject* ret = (PyObject*)self->tb_next; - if (!ret) { - ret = Py_None; - } - Py_INCREF(ret); - return ret; -} - -static int -tb_next_set(PyTracebackObject *self, PyObject *new_next, void *Py_UNUSED(_)) -{ - if (!new_next) { - PyErr_Format(PyExc_TypeError, "can't delete tb_next attribute"); - return -1; - } - - /* We accept None or a traceback object, and map None -> NULL (inverse of - tb_next_get) */ - if (new_next == Py_None) { - new_next = NULL; - } else if (!PyTraceBack_Check(new_next)) { - PyErr_Format(PyExc_TypeError, - "expected traceback object, got '%s'", - Py_TYPE(new_next)->tp_name); - return -1; - } - - /* Check for loops */ - PyTracebackObject *cursor = (PyTracebackObject *)new_next; - while (cursor) { - if (cursor == self) { - PyErr_Format(PyExc_ValueError, "traceback loop detected"); - return -1; - } - cursor = cursor->tb_next; - } - - PyObject *old_next = (PyObject*)self->tb_next; - Py_XINCREF(new_next); - self->tb_next = (PyTracebackObject *)new_next; - Py_XDECREF(old_next); - - return 0; -} - - -static PyMethodDef tb_methods[] = { - {"__dir__", (PyCFunction)tb_dir, METH_NOARGS}, - {NULL, NULL, 0, NULL}, -}; - -static PyMemberDef tb_memberlist[] = { - {"tb_frame", T_OBJECT, OFF(tb_frame), READONLY|PY_AUDIT_READ}, - {"tb_lasti", T_INT, OFF(tb_lasti), READONLY}, - {"tb_lineno", T_INT, OFF(tb_lineno), READONLY}, - {NULL} /* Sentinel */ -}; - -static PyGetSetDef tb_getsetters[] = { - {"tb_next", (getter)tb_next_get, (setter)tb_next_set, NULL, NULL}, - {NULL} /* Sentinel */ -}; - -static void -tb_dealloc(PyTracebackObject *tb) -{ - PyObject_GC_UnTrack(tb); - Py_TRASHCAN_BEGIN(tb, tb_dealloc) - Py_XDECREF(tb->tb_next); - Py_XDECREF(tb->tb_frame); - PyObject_GC_Del(tb); - Py_TRASHCAN_END -} - -static int -tb_traverse(PyTracebackObject *tb, visitproc visit, void *arg) -{ - Py_VISIT(tb->tb_next); - Py_VISIT(tb->tb_frame); - return 0; -} - -static int -tb_clear(PyTracebackObject *tb) -{ - Py_CLEAR(tb->tb_next); - Py_CLEAR(tb->tb_frame); - return 0; -} - -PyTypeObject PyTraceBack_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "traceback", - sizeof(PyTracebackObject), - 0, - (destructor)tb_dealloc, /*tp_dealloc*/ - 0, /*tp_vectorcall_offset*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_as_async*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */ - tb_new__doc__, /* tp_doc */ - (traverseproc)tb_traverse, /* tp_traverse */ - (inquiry)tb_clear, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - tb_methods, /* tp_methods */ - tb_memberlist, /* tp_members */ - tb_getsetters, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - tb_new, /* tp_new */ -}; - - -PyObject* -_PyTraceBack_FromFrame(PyObject *tb_next, PyFrameObject *frame) -{ - assert(tb_next == NULL || PyTraceBack_Check(tb_next)); - assert(frame != NULL); - - return tb_create_raw((PyTracebackObject *)tb_next, frame, frame->f_lasti*sizeof(_Py_CODEUNIT), - PyFrame_GetLineNumber(frame)); -} - - -int -PyTraceBack_Here(PyFrameObject *frame) -{ - PyObject *exc, *val, *tb, *newtb; - PyErr_Fetch(&exc, &val, &tb); - newtb = _PyTraceBack_FromFrame(tb, frame); - if (newtb == NULL) { - _PyErr_ChainExceptions(exc, val, tb); - return -1; - } - PyErr_Restore(exc, val, newtb); - Py_XDECREF(tb); - return 0; -} - -/* Insert a frame into the traceback for (funcname, filename, lineno). */ -void _PyTraceback_Add(const char *funcname, const char *filename, int lineno) -{ - PyObject *globals; - PyCodeObject *code; - PyFrameObject *frame; - PyObject *exc, *val, *tb; - - /* Save and clear the current exception. Python functions must not be - called with an exception set. Calling Python functions happens when - the codec of the filesystem encoding is implemented in pure Python. */ - PyErr_Fetch(&exc, &val, &tb); - - globals = PyDict_New(); - if (!globals) - goto error; - code = PyCode_NewEmpty(filename, funcname, lineno); - if (!code) { - Py_DECREF(globals); - goto error; - } - frame = PyFrame_New(PyThreadState_Get(), code, globals, NULL); - Py_DECREF(globals); - Py_DECREF(code); - if (!frame) - goto error; - frame->f_lineno = lineno; - - PyErr_Restore(exc, val, tb); - PyTraceBack_Here(frame); - Py_DECREF(frame); - return; - -error: - _PyErr_ChainExceptions(exc, val, tb); -} - -static PyObject * -_Py_FindSourceFile(PyObject *filename, char* namebuf, size_t namelen, PyObject *io) -{ - Py_ssize_t i; - PyObject *binary; - PyObject *v; - Py_ssize_t npath; - size_t taillen; - PyObject *syspath; - PyObject *path; - const char* tail; - PyObject *filebytes; - const char* filepath; - Py_ssize_t len; - PyObject* result; - - filebytes = PyUnicode_EncodeFSDefault(filename); - if (filebytes == NULL) { - PyErr_Clear(); - return NULL; - } - filepath = PyBytes_AS_STRING(filebytes); - - /* Search tail of filename in sys.path before giving up */ - tail = strrchr(filepath, SEP); - if (tail == NULL) - tail = filepath; - else - tail++; - taillen = strlen(tail); - - syspath = _PySys_GetObjectId(&PyId_path); - if (syspath == NULL || !PyList_Check(syspath)) - goto error; - npath = PyList_Size(syspath); - - for (i = 0; i < npath; i++) { - v = PyList_GetItem(syspath, i); - if (v == NULL) { - PyErr_Clear(); - break; - } - if (!PyUnicode_Check(v)) - continue; - path = PyUnicode_EncodeFSDefault(v); - if (path == NULL) { - PyErr_Clear(); - continue; - } - len = PyBytes_GET_SIZE(path); - if (len + 1 + (Py_ssize_t)taillen >= (Py_ssize_t)namelen - 1) { - Py_DECREF(path); - continue; /* Too long */ - } - strcpy(namebuf, PyBytes_AS_STRING(path)); - Py_DECREF(path); - if (strlen(namebuf) != (size_t)len) - continue; /* v contains '\0' */ - if (len > 0 && namebuf[len-1] != SEP) - namebuf[len++] = SEP; - strcpy(namebuf+len, tail); - - binary = _PyObject_CallMethodId(io, &PyId_open, "ss", namebuf, "rb"); - if (binary != NULL) { - result = binary; - goto finally; - } - PyErr_Clear(); - } - goto error; - -error: - result = NULL; -finally: - Py_DECREF(filebytes); - return result; -} - -int -_Py_DisplaySourceLine(PyObject *f, PyObject *filename, int lineno, int indent) -{ - int err = 0; - int fd; - int i; - char *found_encoding; - const char *encoding; - PyObject *io; - PyObject *binary; - PyObject *fob = NULL; - PyObject *lineobj = NULL; - PyObject *res; - char buf[MAXPATHLEN+1]; - int kind; - const void *data; - - /* open the file */ - if (filename == NULL) - return 0; - - io = PyImport_ImportModuleNoBlock("io"); - if (io == NULL) - return -1; - binary = _PyObject_CallMethodId(io, &PyId_open, "Os", filename, "rb"); - - if (binary == NULL) { - PyErr_Clear(); - - binary = _Py_FindSourceFile(filename, buf, sizeof(buf), io); - if (binary == NULL) { - Py_DECREF(io); - return -1; - } - } - - /* use the right encoding to decode the file as unicode */ - fd = PyObject_AsFileDescriptor(binary); - if (fd < 0) { - Py_DECREF(io); - Py_DECREF(binary); - return 0; - } - found_encoding = PyTokenizer_FindEncodingFilename(fd, filename); - if (found_encoding == NULL) - PyErr_Clear(); - encoding = (found_encoding != NULL) ? found_encoding : "utf-8"; - /* Reset position */ - if (lseek(fd, 0, SEEK_SET) == (off_t)-1) { - Py_DECREF(io); - Py_DECREF(binary); - PyMem_Free(found_encoding); - return 0; - } - fob = _PyObject_CallMethodId(io, &PyId_TextIOWrapper, "Os", binary, encoding); - Py_DECREF(io); - PyMem_Free(found_encoding); - - if (fob == NULL) { - PyErr_Clear(); - - res = _PyObject_CallMethodIdNoArgs(binary, &PyId_close); - Py_DECREF(binary); - if (res) - Py_DECREF(res); - else - PyErr_Clear(); - return 0; - } - Py_DECREF(binary); - - /* get the line number lineno */ - for (i = 0; i < lineno; i++) { - Py_XDECREF(lineobj); - lineobj = PyFile_GetLine(fob, -1); - if (!lineobj) { - PyErr_Clear(); - err = -1; - break; - } - } - res = _PyObject_CallMethodIdNoArgs(fob, &PyId_close); - if (res) - Py_DECREF(res); - else - PyErr_Clear(); - Py_DECREF(fob); - if (!lineobj || !PyUnicode_Check(lineobj)) { - Py_XDECREF(lineobj); - return err; - } - - /* remove the indentation of the line */ - kind = PyUnicode_KIND(lineobj); - data = PyUnicode_DATA(lineobj); - for (i=0; i < PyUnicode_GET_LENGTH(lineobj); i++) { - Py_UCS4 ch = PyUnicode_READ(kind, data, i); - if (ch != ' ' && ch != '\t' && ch != '\014') - break; - } - if (i) { - PyObject *truncated; - truncated = PyUnicode_Substring(lineobj, i, PyUnicode_GET_LENGTH(lineobj)); - if (truncated) { - Py_DECREF(lineobj); - lineobj = truncated; - } else { - PyErr_Clear(); - } - } - - /* Write some spaces before the line */ - strcpy(buf, " "); - assert (strlen(buf) == 10); - while (indent > 0) { - if (indent < 10) - buf[indent] = '\0'; - err = PyFile_WriteString(buf, f); - if (err != 0) - break; - indent -= 10; - } - - /* finally display the line */ - if (err == 0) - err = PyFile_WriteObject(lineobj, f, Py_PRINT_RAW); - Py_DECREF(lineobj); - if (err == 0) - err = PyFile_WriteString("\n", f); - return err; -} - -static int -tb_displayline(PyObject *f, PyObject *filename, int lineno, PyObject *name) -{ - int err; - PyObject *line; - - if (filename == NULL || name == NULL) - return -1; - line = PyUnicode_FromFormat(" File \"%U\", line %d, in %U\n", - filename, lineno, name); - if (line == NULL) - return -1; - err = PyFile_WriteObject(line, f, Py_PRINT_RAW); - Py_DECREF(line); - if (err != 0) - return err; - /* ignore errors since we can't report them, can we? */ - if (_Py_DisplaySourceLine(f, filename, lineno, 4)) - PyErr_Clear(); - return err; -} - -static const int TB_RECURSIVE_CUTOFF = 3; // Also hardcoded in traceback.py. - -static int -tb_print_line_repeated(PyObject *f, long cnt) -{ - cnt -= TB_RECURSIVE_CUTOFF; - PyObject *line = PyUnicode_FromFormat( - (cnt > 1) - ? " [Previous line repeated %ld more times]\n" - : " [Previous line repeated %ld more time]\n", - cnt); - if (line == NULL) { - return -1; - } - int err = PyFile_WriteObject(line, f, Py_PRINT_RAW); - Py_DECREF(line); - return err; -} - -static int -tb_printinternal(PyTracebackObject *tb, PyObject *f, long limit) -{ - int err = 0; - Py_ssize_t depth = 0; - PyObject *last_file = NULL; - int last_line = -1; - PyObject *last_name = NULL; - long cnt = 0; - PyTracebackObject *tb1 = tb; - while (tb1 != NULL) { - depth++; - tb1 = tb1->tb_next; - } - while (tb != NULL && depth > limit) { - depth--; - tb = tb->tb_next; - } - while (tb != NULL && err == 0) { - PyCodeObject *code = PyFrame_GetCode(tb->tb_frame); - if (last_file == NULL || - code->co_filename != last_file || - last_line == -1 || tb->tb_lineno != last_line || - last_name == NULL || code->co_name != last_name) { - if (cnt > TB_RECURSIVE_CUTOFF) { - err = tb_print_line_repeated(f, cnt); - } - last_file = code->co_filename; - last_line = tb->tb_lineno; - last_name = code->co_name; - cnt = 0; - } - cnt++; - if (err == 0 && cnt <= TB_RECURSIVE_CUTOFF) { - err = tb_displayline(f, code->co_filename, tb->tb_lineno, - code->co_name); - if (err == 0) { - err = PyErr_CheckSignals(); - } - } - Py_DECREF(code); - tb = tb->tb_next; - } - if (err == 0 && cnt > TB_RECURSIVE_CUTOFF) { - err = tb_print_line_repeated(f, cnt); - } - return err; -} - -#define PyTraceBack_LIMIT 1000 - -int -PyTraceBack_Print(PyObject *v, PyObject *f) -{ - int err; - PyObject *limitv; - long limit = PyTraceBack_LIMIT; - - if (v == NULL) - return 0; - if (!PyTraceBack_Check(v)) { - PyErr_BadInternalCall(); - return -1; - } - limitv = PySys_GetObject("tracebacklimit"); - if (limitv && PyLong_Check(limitv)) { - int overflow; - limit = PyLong_AsLongAndOverflow(limitv, &overflow); - if (overflow > 0) { - limit = LONG_MAX; - } - else if (limit <= 0) { - return 0; - } - } - err = PyFile_WriteString("Traceback (most recent call last):\n", f); - if (!err) - err = tb_printinternal((PyTracebackObject *)v, f, limit); - return err; -} - -/* Format an integer in range [0; 0xffffffff] to decimal and write it - into the file fd. - - This function is signal safe. */ - -void -_Py_DumpDecimal(int fd, size_t value) -{ - /* maximum number of characters required for output of %lld or %p. - We need at most ceil(log10(256)*SIZEOF_LONG_LONG) digits, - plus 1 for the null byte. 53/22 is an upper bound for log10(256). */ - char buffer[1 + (sizeof(size_t)*53-1) / 22 + 1]; - char *ptr, *end; - - end = &buffer[Py_ARRAY_LENGTH(buffer) - 1]; - ptr = end; - *ptr = '\0'; - do { - --ptr; - assert(ptr >= buffer); - *ptr = '0' + (value % 10); - value /= 10; - } while (value); - - _Py_write_noraise(fd, ptr, end - ptr); -} - -/* Format an integer as hexadecimal with width digits into fd file descriptor. - The function is signal safe. */ -void -_Py_DumpHexadecimal(int fd, uintptr_t value, Py_ssize_t width) -{ - char buffer[sizeof(uintptr_t) * 2 + 1], *ptr, *end; - const Py_ssize_t size = Py_ARRAY_LENGTH(buffer) - 1; - - if (width > size) - width = size; - /* it's ok if width is negative */ - - end = &buffer[size]; - ptr = end; - *ptr = '\0'; - do { - --ptr; - assert(ptr >= buffer); - *ptr = Py_hexdigits[value & 15]; - value >>= 4; - } while ((end - ptr) < width || value); - - _Py_write_noraise(fd, ptr, end - ptr); -} - -void -_Py_DumpASCII(int fd, PyObject *text) -{ - PyASCIIObject *ascii = (PyASCIIObject *)text; - Py_ssize_t i, size; - int truncated; - int kind; - void *data = NULL; - wchar_t *wstr = NULL; - Py_UCS4 ch; - - if (!PyUnicode_Check(text)) - return; - - size = ascii->length; - kind = ascii->state.kind; - if (kind == PyUnicode_WCHAR_KIND) { - wstr = ((PyASCIIObject *)text)->wstr; - if (wstr == NULL) - return; - size = ((PyCompactUnicodeObject *)text)->wstr_length; - } - else if (ascii->state.compact) { - if (ascii->state.ascii) - data = ((PyASCIIObject*)text) + 1; - else - data = ((PyCompactUnicodeObject*)text) + 1; - } - else { - data = ((PyUnicodeObject *)text)->data.any; - if (data == NULL) - return; - } - - if (MAX_STRING_LENGTH < size) { - size = MAX_STRING_LENGTH; - truncated = 1; - } - else { - truncated = 0; - } - - // Is an ASCII string? - if (ascii->state.ascii) { - assert(kind == PyUnicode_1BYTE_KIND); - char *str = data; - - int need_escape = 0; - for (i=0; i < size; i++) { - ch = str[i]; - if (!(' ' <= ch && ch <= 126)) { - need_escape = 1; - break; - } - } - if (!need_escape) { - // The string can be written with a single write() syscall - _Py_write_noraise(fd, str, size); - goto done; - } - } - - for (i=0; i < size; i++) { - if (kind != PyUnicode_WCHAR_KIND) - ch = PyUnicode_READ(kind, data, i); - else - ch = wstr[i]; - if (' ' <= ch && ch <= 126) { - /* printable ASCII character */ - char c = (char)ch; - _Py_write_noraise(fd, &c, 1); - } - else if (ch <= 0xff) { - PUTS(fd, "\\x"); - _Py_DumpHexadecimal(fd, ch, 2); - } - else if (ch <= 0xffff) { - PUTS(fd, "\\u"); - _Py_DumpHexadecimal(fd, ch, 4); - } - else { - PUTS(fd, "\\U"); - _Py_DumpHexadecimal(fd, ch, 8); - } - } - -done: - if (truncated) { - PUTS(fd, "..."); - } -} - -/* Write a frame into the file fd: "File "xxx", line xxx in xxx". - - This function is signal safe. */ - -static void -dump_frame(int fd, PyFrameObject *frame) -{ - PyCodeObject *code = PyFrame_GetCode(frame); - PUTS(fd, " File "); - if (code->co_filename != NULL - && PyUnicode_Check(code->co_filename)) - { - PUTS(fd, "\""); - _Py_DumpASCII(fd, code->co_filename); - PUTS(fd, "\""); - } else { - PUTS(fd, "???"); - } - - int lineno = PyFrame_GetLineNumber(frame); - PUTS(fd, ", line "); - if (lineno >= 0) { - _Py_DumpDecimal(fd, (size_t)lineno); - } - else { - PUTS(fd, "???"); - } - PUTS(fd, " in "); - - if (code->co_name != NULL - && PyUnicode_Check(code->co_name)) { - _Py_DumpASCII(fd, code->co_name); - } - else { - PUTS(fd, "???"); - } - - PUTS(fd, "\n"); - Py_DECREF(code); -} - -static void -dump_traceback(int fd, PyThreadState *tstate, int write_header) -{ - PyFrameObject *frame; - unsigned int depth; - - if (write_header) { - PUTS(fd, "Stack (most recent call first):\n"); - } - - // Use a borrowed reference. Avoid Py_INCREF/Py_DECREF, since this function - // can be called in a signal handler by the faulthandler module which must - // not modify Python objects. - frame = tstate->frame; - if (frame == NULL) { - PUTS(fd, " <no Python frame>\n"); - return; - } - - depth = 0; - while (1) { - if (MAX_FRAME_DEPTH <= depth) { - PUTS(fd, " ...\n"); - break; - } - if (!PyFrame_Check(frame)) { - break; - } - dump_frame(fd, frame); - PyFrameObject *back = frame->f_back; - - if (back == NULL) { - break; - } - frame = back; - depth++; - } -} - -/* Dump the traceback of a Python thread into fd. Use write() to write the - traceback and retry if write() is interrupted by a signal (failed with - EINTR), but don't call the Python signal handler. - - The caller is responsible to call PyErr_CheckSignals() to call Python signal - handlers if signals were received. */ -void -_Py_DumpTraceback(int fd, PyThreadState *tstate) -{ - dump_traceback(fd, tstate, 1); -} - -/* Write the thread identifier into the file 'fd': "Current thread 0xHHHH:\" if - is_current is true, "Thread 0xHHHH:\n" otherwise. - - This function is signal safe. */ - -static void -write_thread_id(int fd, PyThreadState *tstate, int is_current) -{ - if (is_current) - PUTS(fd, "Current thread 0x"); - else - PUTS(fd, "Thread 0x"); - _Py_DumpHexadecimal(fd, - tstate->thread_id, - sizeof(unsigned long) * 2); - PUTS(fd, " (most recent call first):\n"); -} - -/* Dump the traceback of all Python threads into fd. Use write() to write the - traceback and retry if write() is interrupted by a signal (failed with - EINTR), but don't call the Python signal handler. - - The caller is responsible to call PyErr_CheckSignals() to call Python signal - handlers if signals were received. */ -const char* -_Py_DumpTracebackThreads(int fd, PyInterpreterState *interp, - PyThreadState *current_tstate) -{ - PyThreadState *tstate; - unsigned int nthreads; - - if (current_tstate == NULL) { - /* _Py_DumpTracebackThreads() is called from signal handlers by - faulthandler. - - SIGSEGV, SIGFPE, SIGABRT, SIGBUS and SIGILL are synchronous signals - and are thus delivered to the thread that caused the fault. Get the - Python thread state of the current thread. - - PyThreadState_Get() doesn't give the state of the thread that caused - the fault if the thread released the GIL, and so - _PyThreadState_GET() cannot be used. Read the thread specific - storage (TSS) instead: call PyGILState_GetThisThreadState(). */ - current_tstate = PyGILState_GetThisThreadState(); - } - - if (interp == NULL) { - if (current_tstate == NULL) { - interp = _PyGILState_GetInterpreterStateUnsafe(); - if (interp == NULL) { - /* We need the interpreter state to get Python threads */ - return "unable to get the interpreter state"; - } - } - else { - interp = current_tstate->interp; - } - } - assert(interp != NULL); - - /* Get the current interpreter from the current thread */ - tstate = PyInterpreterState_ThreadHead(interp); - if (tstate == NULL) - return "unable to get the thread head state"; - - /* Dump the traceback of each thread */ - tstate = PyInterpreterState_ThreadHead(interp); - nthreads = 0; - _Py_BEGIN_SUPPRESS_IPH - do - { - if (nthreads != 0) - PUTS(fd, "\n"); - if (nthreads >= MAX_NTHREADS) { - PUTS(fd, "...\n"); - break; - } - write_thread_id(fd, tstate, tstate == current_tstate); - if (tstate == current_tstate && tstate->interp->gc.collecting) { - PUTS(fd, " Garbage-collecting\n"); - } - dump_traceback(fd, tstate, 0); - tstate = PyThreadState_Next(tstate); - nthreads++; - } while (tstate != NULL); - _Py_END_SUPPRESS_IPH - - return NULL; -} - diff --git a/contrib/tools/python3/src/Python/wordcode_helpers.h b/contrib/tools/python3/src/Python/wordcode_helpers.h deleted file mode 100644 index c8f7a0f41f9..00000000000 --- a/contrib/tools/python3/src/Python/wordcode_helpers.h +++ /dev/null @@ -1,44 +0,0 @@ -/* This file contains code shared by the compiler and the peephole - optimizer. - */ - -#ifdef WORDS_BIGENDIAN -# define PACKOPARG(opcode, oparg) ((_Py_CODEUNIT)(((opcode) << 8) | (oparg))) -#else -# define PACKOPARG(opcode, oparg) ((_Py_CODEUNIT)(((oparg) << 8) | (opcode))) -#endif - -/* Minimum number of code units necessary to encode instruction with - EXTENDED_ARGs */ -static int -instrsize(unsigned int oparg) -{ - return oparg <= 0xff ? 1 : - oparg <= 0xffff ? 2 : - oparg <= 0xffffff ? 3 : - 4; -} - -/* Spits out op/oparg pair using ilen bytes. codestr should be pointed at the - desired location of the first EXTENDED_ARG */ -static void -write_op_arg(_Py_CODEUNIT *codestr, unsigned char opcode, - unsigned int oparg, int ilen) -{ - switch (ilen) { - case 4: - *codestr++ = PACKOPARG(EXTENDED_ARG, (oparg >> 24) & 0xff); - /* fall through */ - case 3: - *codestr++ = PACKOPARG(EXTENDED_ARG, (oparg >> 16) & 0xff); - /* fall through */ - case 2: - *codestr++ = PACKOPARG(EXTENDED_ARG, (oparg >> 8) & 0xff); - /* fall through */ - case 1: - *codestr++ = PACKOPARG(opcode, oparg & 0xff); - break; - default: - Py_UNREACHABLE(); - } -} |
