diff --git a/amalgamate.py b/amalgamate.py index 1a72f240..1320077c 100644 --- a/amalgamate.py +++ b/amalgamate.py @@ -2,7 +2,7 @@ with open("src/opcodes.h", "rt", encoding='utf-8') as f: OPCODES_TEXT = f.read() pipeline = [ - ["__stl__.h", "str.h", "builtins.h", "error.h"], + ["__stl__.h", "str.h", "safestl.h", "builtins.h", "error.h"], ["obj.h", "iter.h", "parser.h", "pointer.h", "codeobject.h"], ["vm.h", "compiler.h", "repl.h"], ["pocketpy.h"] diff --git a/src/codeobject.h b/src/codeobject.h index f3353c5d..ea19fbe5 100644 --- a/src/codeobject.h +++ b/src/codeobject.h @@ -139,7 +139,7 @@ public: return code->src->snapshot(line); } - int stackSize() const { + inline int stackSize() const { return s_data.size(); } @@ -148,6 +148,7 @@ public: } inline PyVar __pop(){ + if(s_data.empty()) throw std::runtime_error("s_data.empty() is true"); PyVar v = s_data.back(); s_data.pop_back(); return v; @@ -160,10 +161,11 @@ public: } inline PyVar topValue(VM* vm){ + if(s_data.empty()) throw std::runtime_error("s_data.empty() is true"); return __deref_pointer(vm, s_data.back()); } - inline PyVar topNValue(VM* vm, int n=-1){ + inline PyVar __topValueN(VM* vm, int n=-1){ return __deref_pointer(vm, s_data[s_data.size() + n]); } diff --git a/src/error.h b/src/error.h index a81c9019..d6e0f732 100644 --- a/src/error.h +++ b/src/error.h @@ -1,7 +1,6 @@ #pragma once -#include "__stl__.h" -#include "str.h" +#include "safestl.h" class NeedMoreLines { public: diff --git a/src/obj.h b/src/obj.h index 6a60ac73..ec7c6f2f 100644 --- a/src/obj.h +++ b/src/obj.h @@ -1,7 +1,6 @@ #pragma once -#include "__stl__.h" -#include "str.h" +#include "safestl.h" typedef int64_t _Int; typedef double _Float; @@ -13,43 +12,12 @@ const _Float _FLOAT_INF_NEG = -INFINITY; #define PK_VERSION "0.2.3" -class PyObject; class CodeObject; class BasePointer; class VM; - class PkExportedResource {}; -typedef std::shared_ptr PyVar; -typedef PyVar PyVarOrNull; - -class PyVarList: public std::vector { - PyVar& at(size_t) = delete; - - inline void __checkIndex(size_t i) const { - if (i >= size()){ - auto msg = "std::vector index out of range, " + std::to_string(i) + " not in [0, " + std::to_string(size()) + ")"; - throw std::out_of_range(msg); - } - } -public: - PyVar& operator[](size_t i) { - __checkIndex(i); - return std::vector::operator[](i); - } - - const PyVar& operator[](size_t i) const { - __checkIndex(i); - return std::vector::operator[](i); - } - - // define constructors the same as std::vector - using std::vector::vector; -}; - -typedef std::unordered_map<_Str, PyVar> PyVarDict; typedef std::shared_ptr _Pointer; - typedef PyVar (*_CppFunc)(VM*, PyVarList); typedef std::shared_ptr _Code; diff --git a/src/safestl.h b/src/safestl.h new file mode 100644 index 00000000..b3fedf09 --- /dev/null +++ b/src/safestl.h @@ -0,0 +1,54 @@ +#pragma once + +#include "__stl__.h" +#include "str.h" + +class PyObject; +typedef std::shared_ptr PyVar; +typedef PyVar PyVarOrNull; + +class PyVarList: public std::vector { + PyVar& at(size_t) = delete; + + inline void __checkIndex(size_t i) const { + if (i >= size()){ + auto msg = "std::vector index out of range, " + std::to_string(i) + " not in [0, " + std::to_string(size()) + ")"; + throw std::out_of_range(msg); + } + } +public: + PyVar& operator[](size_t i) { + __checkIndex(i); + return std::vector::operator[](i); + } + + const PyVar& operator[](size_t i) const { + __checkIndex(i); + return std::vector::operator[](i); + } + + // define constructors the same as std::vector + using std::vector::vector; +}; + + +class PyVarDict: public std::unordered_map<_Str, PyVar> { + PyVar& at(const _Str&) = delete; + +public: + PyVar& operator[](const _Str& key) { + return std::unordered_map<_Str, PyVar>::operator[](key); + } + + const PyVar& operator[](const _Str& key) const { + auto it = find(key); + if (it == end()){ + auto msg = "std::unordered_map key not found, '" + key.str() + "'"; + throw std::out_of_range(msg); + } + return it->second; + } + + // define constructors the same as std::unordered_map + using std::unordered_map<_Str, PyVar>::unordered_map; +}; \ No newline at end of file diff --git a/src/vm.h b/src/vm.h index b9f186b2..ebbf7018 100644 --- a/src/vm.h +++ b/src/vm.h @@ -124,7 +124,7 @@ private: } break; case OP_LIST_APPEND: { PyVar obj = frame->popValue(this); - PyVar list = frame->topNValue(this, -2); + PyVar list = frame->__topValueN(this, -2); fastCall(list, "append", {list, obj}); } break; case OP_STORE_FUNCTION: