Răsfoiți Sursa

Merge branch 'main' of https://github.com/blueloveTH/pocketpy

blueloveTH 2 ani în urmă
părinte
comite
5729c0f377

+ 1 - 0
.gitignore

@@ -33,3 +33,4 @@ pocketpy.dSYM
 main
 
 pypi/
+libpocketpy.dylib

+ 2 - 2
CMakeLists.txt

@@ -18,9 +18,9 @@ if(NOT ${PREBUILD_RESULT} EQUAL 0)
 endif()
 
 if(MSVC)
-    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /GR- /EHsc /utf-8 /O2")
+    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc /utf-8 /O2")
 else()
-    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti -fexceptions -O2")
+    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fexceptions -O2")
 endif()
 
 include_directories(${CMAKE_CURRENT_LIST_DIR}/include)

+ 0 - 1
README.md

@@ -40,7 +40,6 @@ To compile it with your project, these flags must be set:
 
 + `--std=c++17` flag must be set
 + Exception must be enabled
-+ RTTI is not required
 
 ### Example
 

+ 4 - 2
build.sh

@@ -1,14 +1,16 @@
 python3 prebuild.py
 SRC=$(find src/ -name "*.cpp")
-FLAGS="-std=c++17 -fno-rtti -O2 -stdlib=libc++ -Wfatal-errors -Iinclude"
+FLAGS="-std=c++17 -O2 -stdlib=libc++ -Wfatal-errors -Iinclude"
 
 if [[ "$OSTYPE" == "darwin"* ]]; then
     LIB_EXTENSION=".dylib"
     FLAGS="$FLAGS -undefined dynamic_lookup"
+    LINK_FLAGS=""
 else
     LIB_EXTENSION=".so"
+    LINK_FLAGS="-Wl,-rpath=."
 fi
 clang++ $FLAGS -o libpocketpy$LIB_EXTENSION $SRC -fPIC -shared -ldl
 
 # compile main.cpp and link to libpocketpy.so
-clang++ $FLAGS -o main src2/main.cpp -L. -lpocketpy -Wl,-rpath=.
+clang++ $FLAGS -o main src2/main.cpp -L. -lpocketpy $LINK_FLAGS

+ 1 - 1
build_web.sh

@@ -4,4 +4,4 @@ rm -rf web/lib
 mkdir web/lib
 
 SRC=$(find src/ -name "*.cpp")
-em++ $SRC -Iinclude/ -fno-rtti -fexceptions -O3 -sEXPORTED_FUNCTIONS=_pkpy_new_repl,_pkpy_repl_input,_pkpy_new_vm -sEXPORTED_RUNTIME_METHODS=ccall -o web/lib/pocketpy.js
+em++ $SRC -Iinclude/ -fexceptions -O3 -sEXPORTED_FUNCTIONS=_pkpy_new_repl,_pkpy_repl_input,_pkpy_new_vm -sEXPORTED_RUNTIME_METHODS=ccall -o web/lib/pocketpy.js

+ 2 - 2
c_bindings/test.c

@@ -413,11 +413,11 @@ int main(int argc, char** argv) {
 
     PRINT_TITLE("test py_repr");
     check(pkpy_eval(vm, "['1', 2, (3, '4')]"));
-    check(pkpy_py_repr(vm, -1));
+    check(pkpy_py_repr(vm));
     check(pkpy_to_string(vm, -1, &r_string));
     for(int i = 0; i < r_string.size; i++) putchar(r_string.data[i]);
     putchar('\n');
-    check(pkpy_pop(vm, 2));
+    check(pkpy_pop_top(vm));
     check(pkpy_stack_size(vm) == 0);
     return 0;
 }

+ 8 - 4
docs/C-API/stack.md

@@ -6,6 +6,10 @@ order: 8
 
 ### Basic manipulation
 
++ `bool pkpy_dup(pkpy_vm*, int)`
+
+    Duplicate the value at the given index.
+
 + `bool pkpy_pop(pkpy_vm*, int)`
 
     Pop `n` values from the stack.
@@ -70,7 +74,7 @@ PK_EXPORT bool pkpy_is_none(pkpy_vm*, int i);
 
 + `pkpy_push_null(pkpy_vm*)`
 
-    Push a `PY_NULL` onto the stack.
+    Push a `PY_NULL` onto the stack. It is used for `pkpy_vectorcall`.
 
 + `pkpy_push_function(pkpy_vm*, const char* sig, pkpy_CFunction f)`
 
@@ -140,10 +144,10 @@ PK_EXPORT bool pkpy_is_none(pkpy_vm*, int i);
     ```
     [obj] -> [obj.<name> self]
     ```
-+ `bool pkpy_py_repr(pkpy_vm*, int i)`
++ `bool pkpy_py_repr(pkpy_vm*)`
 
-    Get the repr of the value at the given index and push it onto the stack.
+    Get the repr of the value at the top of the stack.
 
     ```
-    [..., value, ...] -> [..., value, ..., repr(value)]
+    [value] -> [repr(value)]
     ```

+ 0 - 1
docs/quick-start/installation.md

@@ -22,7 +22,6 @@ To compile it with your project, these flags must be set:
 
 + `--std=c++17` flag must be set
 + Exception must be enabled
-+ RTTI is not required
 
 ### Example
 

+ 2 - 41
include/pocketpy/expr.h

@@ -16,8 +16,6 @@ struct Expr{
     int line = 0;
     virtual ~Expr() = default;
     virtual void emit(CodeEmitContext* ctx) = 0;
-    virtual std::string str() const = 0;
-
     virtual bool is_literal() const { return false; }
     virtual bool is_json_object() const { return false; }
     virtual bool is_attrib() const { return false; }
@@ -26,6 +24,8 @@ struct Expr{
     virtual bool is_tuple() const { return false; }
     bool is_starred() const { return star_level() > 0; }
 
+    std::string str() const { PK_ASSERT(false); }
+
     // for OP_DELETE_XXX
     [[nodiscard]] virtual bool emit_del(CodeEmitContext* ctx) {
         PK_UNUSED(ctx);
@@ -70,9 +70,6 @@ struct NameExpr: Expr{
     StrName name;
     NameScope scope;
     NameExpr(StrName name, NameScope scope): name(name), scope(scope) {}
-
-    std::string str() const override { return fmt("Name(", name.escape(), ")"); }
-
     void emit(CodeEmitContext* ctx) override;
     bool emit_del(CodeEmitContext* ctx) override;
     bool emit_store(CodeEmitContext* ctx) override;
@@ -81,7 +78,6 @@ struct NameExpr: Expr{
 struct InvertExpr: Expr{
     Expr_ child;
     InvertExpr(Expr_&& child): child(std::move(child)) {}
-    std::string str() const override { return "Invert()"; }
     void emit(CodeEmitContext* ctx) override;
 };
 
@@ -89,7 +85,6 @@ struct StarredExpr: Expr{
     int level;
     Expr_ child;
     StarredExpr(int level, Expr_&& child): level(level), child(std::move(child)) {}
-    std::string str() const override { return fmt("Starred(level=", level, ")"); }
     int star_level() const override { return level; }
     void emit(CodeEmitContext* ctx) override;
     bool emit_store(CodeEmitContext* ctx) override;
@@ -98,22 +93,18 @@ struct StarredExpr: Expr{
 struct NotExpr: Expr{
     Expr_ child;
     NotExpr(Expr_&& child): child(std::move(child)) {}
-    std::string str() const override { return "Not()"; }
-
     void emit(CodeEmitContext* ctx) override;
 };
 
 struct AndExpr: Expr{
     Expr_ lhs;
     Expr_ rhs;
-    std::string str() const override { return "And()"; }
     void emit(CodeEmitContext* ctx) override;
 };
 
 struct OrExpr: Expr{
     Expr_ lhs;
     Expr_ rhs;
-    std::string str() const override { return "Or()"; }
     void emit(CodeEmitContext* ctx) override;
 };
 
@@ -121,7 +112,6 @@ struct OrExpr: Expr{
 struct Literal0Expr: Expr{
     TokenIndex token;
     Literal0Expr(TokenIndex token): token(token) {}
-    std::string str() const override { return TK_STR(token); }
     bool is_json_object() const override { return true; }
 
     void emit(CodeEmitContext* ctx) override;
@@ -130,14 +120,12 @@ struct Literal0Expr: Expr{
 struct LongExpr: Expr{
     Str s;
     LongExpr(const Str& s): s(s) {}
-    std::string str() const override { return s.str(); }
     void emit(CodeEmitContext* ctx) override;
 };
 
 struct BytesExpr: Expr{
     Str s;
     BytesExpr(const Str& s): s(s) {}
-    std::string str() const override { return s.str(); }
     void emit(CodeEmitContext* ctx) override;
 };
 
@@ -145,7 +133,6 @@ struct BytesExpr: Expr{
 struct LiteralExpr: Expr{
     TokenValue value;
     LiteralExpr(TokenValue value): value(value) {}
-    std::string str() const override;
     void emit(CodeEmitContext* ctx) override;
     bool is_literal() const override { return true; }
     bool is_json_object() const override { return true; }
@@ -154,8 +141,6 @@ struct LiteralExpr: Expr{
 struct NegatedExpr: Expr{
     Expr_ child;
     NegatedExpr(Expr_&& child): child(std::move(child)) {}
-    std::string str() const override { return "Negated()"; }
-
     void emit(CodeEmitContext* ctx) override;
     bool is_json_object() const override { return child->is_literal(); }
 };
@@ -164,14 +149,12 @@ struct SliceExpr: Expr{
     Expr_ start;
     Expr_ stop;
     Expr_ step;
-    std::string str() const override { return "Slice()"; }
     void emit(CodeEmitContext* ctx) override;
 };
 
 struct DictItemExpr: Expr{
     Expr_ key;      // maybe nullptr if it is **kwargs
     Expr_ value;
-    std::string str() const override { return "DictItem()"; }
     int star_level() const override { return value->star_level(); }
     void emit(CodeEmitContext* ctx) override;
 };
@@ -189,8 +172,6 @@ struct SequenceExpr: Expr{
 
 struct ListExpr: SequenceExpr{
     using SequenceExpr::SequenceExpr;
-    std::string str() const override { return "List()"; }
-
     Opcode opcode() const override {
         for(auto& e: items) if(e->is_starred()) return OP_BUILD_LIST_UNPACK;
         return OP_BUILD_LIST;
@@ -201,7 +182,6 @@ struct ListExpr: SequenceExpr{
 
 struct DictExpr: SequenceExpr{
     using SequenceExpr::SequenceExpr;
-    std::string str() const override { return "Dict()"; }
     Opcode opcode() const override {
         for(auto& e: items) if(e->is_starred()) return OP_BUILD_DICT_UNPACK;
         return OP_BUILD_DICT;
@@ -212,7 +192,6 @@ struct DictExpr: SequenceExpr{
 
 struct SetExpr: SequenceExpr{
     using SequenceExpr::SequenceExpr;
-    std::string str() const override { return "Set()"; }
     Opcode opcode() const override {
         for(auto& e: items) if(e->is_starred()) return OP_BUILD_SET_UNPACK;
         return OP_BUILD_SET;
@@ -221,7 +200,6 @@ struct SetExpr: SequenceExpr{
 
 struct TupleExpr: SequenceExpr{
     using SequenceExpr::SequenceExpr;
-    std::string str() const override { return "Tuple()"; }
     bool is_tuple() const override { return true; }
     Opcode opcode() const override {
         for(auto& e: items) if(e->is_starred()) return OP_BUILD_TUPLE_UNPACK;
@@ -247,24 +225,20 @@ struct CompExpr: Expr{
 struct ListCompExpr: CompExpr{
     Opcode op0() override { return OP_BUILD_LIST; }
     Opcode op1() override { return OP_LIST_APPEND; }
-    std::string str() const override { return "ListComp()"; }
 };
 
 struct DictCompExpr: CompExpr{
     Opcode op0() override { return OP_BUILD_DICT; }
     Opcode op1() override { return OP_DICT_ADD; }
-    std::string str() const override { return "DictComp()"; }
 };
 
 struct SetCompExpr: CompExpr{
     Opcode op0() override { return OP_BUILD_SET; }
     Opcode op1() override { return OP_SET_ADD; }
-    std::string str() const override { return "SetComp()"; }
 };
 
 struct LambdaExpr: Expr{
     FuncDecl_ decl;
-    std::string str() const override { return "Lambda()"; }
 
     LambdaExpr(FuncDecl_ decl): decl(decl) {}
 
@@ -277,10 +251,6 @@ struct LambdaExpr: Expr{
 struct FStringExpr: Expr{
     Str src;
     FStringExpr(const Str& src): src(src) {}
-    std::string str() const override {
-        return fmt("f", src.escape());
-    }
-
     void _load_simple_expr(CodeEmitContext* ctx, Str expr);
     void emit(CodeEmitContext* ctx) override;
 };
@@ -288,8 +258,6 @@ struct FStringExpr: Expr{
 struct SubscrExpr: Expr{
     Expr_ a;
     Expr_ b;
-    std::string str() const override { return "Subscr()"; }
-
     void emit(CodeEmitContext* ctx) override;
     bool emit_del(CodeEmitContext* ctx) override;
     bool emit_store(CodeEmitContext* ctx) override;
@@ -300,7 +268,6 @@ struct AttribExpr: Expr{
     Str b;
     AttribExpr(Expr_ a, const Str& b): a(std::move(a)), b(b) {}
     AttribExpr(Expr_ a, Str&& b): a(std::move(a)), b(std::move(b)) {}
-    std::string str() const override { return "Attrib()"; }
 
     void emit(CodeEmitContext* ctx) override;
     bool emit_del(CodeEmitContext* ctx) override;
@@ -314,14 +281,11 @@ struct CallExpr: Expr{
     std::vector<Expr_> args;
     // **a will be interpreted as a special keyword argument: {"**": a}
     std::vector<std::pair<Str, Expr_>> kwargs;
-    std::string str() const override { return "Call()"; }
     void emit(CodeEmitContext* ctx) override;
 };
 
 struct GroupedExpr: Expr{
     Expr_ a;
-    std::string str() const override { return "Grouped()"; }
-
     GroupedExpr(Expr_&& a): a(std::move(a)) {}
 
     void emit(CodeEmitContext* ctx) override{
@@ -341,8 +305,6 @@ struct BinaryExpr: Expr{
     TokenIndex op;
     Expr_ lhs;
     Expr_ rhs;
-    std::string str() const override { return TK_STR(op); }
-
     bool is_compare() const override;
     void _emit_compare(CodeEmitContext* ctx, std::vector<int>& jmps);
     void emit(CodeEmitContext* ctx) override;
@@ -353,7 +315,6 @@ struct TernaryExpr: Expr{
     Expr_ cond;
     Expr_ true_expr;
     Expr_ false_expr;
-    std::string str() const override { return "Ternary()"; }
     void emit(CodeEmitContext* ctx) override;
 };
 

+ 3 - 2
include/pocketpy/obj.h

@@ -61,11 +61,12 @@ struct Bytes{
         return _data != rhs._data;
     }
 
-    std::string str() const noexcept { return std::string(_data.begin(), _data.end()); }
+    Str str() const noexcept { return Str(_data.data(), _data.size()); }
 
     Bytes() : _data(), _ok(false) {}
     Bytes(std::vector<char>&& data) : _data(std::move(data)), _ok(true) {}
-    Bytes(const std::string& data) : _data(data.begin(), data.end()), _ok(true) {}
+    Bytes(const Str& data) : _data(data.begin(), data.end()), _ok(true) {}
+    Bytes(std::string_view sv): _data(sv.begin(), sv.end()), _ok(true) {}
     operator bool() const noexcept { return _ok; }
 };
 

+ 2 - 1
include/pocketpy/pocketpy_c.h

@@ -27,6 +27,7 @@ PK_EXPORT bool pkpy_exec(pkpy_vm*, const char* source);
 PK_EXPORT bool pkpy_exec_2(pkpy_vm*, const char* source, const char* filename, int mode, const char* module);
 
 /* Stack Manipulation */
+PK_EXPORT bool pkpy_dup(pkpy_vm*, int);
 PK_EXPORT bool pkpy_pop(pkpy_vm*, int);
 PK_EXPORT bool pkpy_pop_top(pkpy_vm*);
 PK_EXPORT bool pkpy_dup_top(pkpy_vm*);
@@ -75,7 +76,7 @@ PK_EXPORT bool pkpy_setglobal(pkpy_vm*, pkpy_CName);
 PK_EXPORT bool pkpy_eval(pkpy_vm*, const char* source);
 PK_EXPORT bool pkpy_unpack_sequence(pkpy_vm*, int size);
 PK_EXPORT bool pkpy_get_unbound_method(pkpy_vm*, pkpy_CName);
-PK_EXPORT bool pkpy_py_repr(pkpy_vm*, int i);
+PK_EXPORT bool pkpy_py_repr(pkpy_vm*);
 
 /* Error Handling */
 PK_EXPORT bool pkpy_error(pkpy_vm*, const char* name, pkpy_CString);

+ 0 - 6
plugins/flutter/src/CMakeLists.txt

@@ -13,12 +13,6 @@ add_library(pocketpy SHARED
   "pocketpy.cpp"
 )
 
-if (NOT MSVC)
-  target_compile_options(pocketpy PRIVATE -fno-rtti)
-else()
-  target_compile_options(pocketpy PRIVATE /GR- /EHsc)
-endif()
-
 set_target_properties(pocketpy PROPERTIES
   PUBLIC_HEADER pocketpy.h
   OUTPUT_NAME "pocketpy"

+ 1 - 1
run_profile.sh

@@ -1,6 +1,6 @@
 python3 prebuild.py
 SRC=$(find src/ -name "*.cpp")
-clang++ -pg -O1 -std=c++17 -fno-rtti -stdlib=libc++ -Wfatal-errors -o main $SRC -Iinclude -ldl
+clang++ -pg -O1 -std=c++17 -stdlib=libc++ -Wfatal-errors -o main $SRC -Iinclude -ldl
 time ./main benchmarks/fib.py
 mv benchmarks/gmon.out .
 gprof pocketpy gmon.out > gprof.txt

+ 1 - 1
run_tests.sh

@@ -1,6 +1,6 @@
 python3 prebuild.py
 SRC=$(find src/ -name "*.cpp")
-clang++ -std=c++17 -fno-rtti --coverage -O1 -stdlib=libc++ -Wfatal-errors -o main src2/main.cpp $SRC -Iinclude -ldl
+clang++ -std=c++17 --coverage -O1 -stdlib=libc++ -Wfatal-errors -o main src2/main.cpp $SRC -Iinclude -ldl
 python3 scripts/run_tests.py
 rm -rf .coverage
 mkdir .coverage

+ 0 - 14
src/expr.cpp

@@ -196,20 +196,6 @@ namespace pkpy{
         ctx->emit(OP_BUILD_BYTES, BC_NOARG, line);
     }
 
-    std::string LiteralExpr::str() const{
-        if(std::holds_alternative<i64>(value)){
-            return std::to_string(std::get<i64>(value));
-        }
-        if(std::holds_alternative<f64>(value)){
-            return std::to_string(std::get<f64>(value));
-        }
-        if(std::holds_alternative<Str>(value)){
-            Str s = std::get<Str>(value).escape();
-            return s.str();
-        }
-        FATAL_ERROR();
-    }
-
     void LiteralExpr::emit(CodeEmitContext* ctx) {
         VM* vm = ctx->vm;
         PyObject* obj = nullptr;

+ 1 - 1
src/io.cpp

@@ -40,7 +40,7 @@ Bytes _default_import_handler(const Str& name){
             size_t sz = fread(buffer.data(), 1, buffer.size(), io.fp);
             PK_UNUSED(sz);
             Bytes b(std::move(buffer));
-            if(io.is_text()) return VAR(Str(b.str()));
+            if(io.is_text()) return VAR(b.str());
             return VAR(std::move(b));
         });
 

+ 2 - 1
src/pocketpy.cpp

@@ -916,7 +916,8 @@ void init_builtins(VM* _vm) {
 
     _vm->bind__hash__(_vm->tp_bytes, [](VM* vm, PyObject* obj) {
         const Bytes& self = _CAST(Bytes&, obj);
-        return (i64)std::hash<std::string>()(self.str());
+        std::string_view view(self.data(), self.size());
+        return (i64)std::hash<std::string_view>()(view);
     });
 
     _vm->bind__repr__(_vm->tp_bytes, [](VM* vm, PyObject* obj) {

+ 14 - 4
src/pocketpy_c.cpp

@@ -89,6 +89,16 @@ bool pkpy_exec_2(pkpy_vm* vm_handle, const char* source, const char* filename, i
     return res != nullptr;
 }
 
+bool pkpy_dup(pkpy_vm* vm_handle, int n){
+    VM* vm = (VM*) vm_handle;
+    PK_ASSERT_NO_ERROR()
+    PK_PROTECTED(
+        PyObject* item = stack_item(vm, n);
+        vm->s_data.push(item);
+    )
+    return true;
+}
+
 bool pkpy_pop(pkpy_vm* vm_handle, int n){
     VM* vm = (VM*) vm_handle;
     PK_ASSERT_NO_ERROR()
@@ -461,15 +471,15 @@ bool pkpy_get_unbound_method(pkpy_vm* vm_handle, pkpy_CName name){
     return true;
 }
 
-bool pkpy_py_repr(pkpy_vm* vm_handle, int i) {
+bool pkpy_py_repr(pkpy_vm* vm_handle) {
     VM* vm = (VM*) vm_handle;
     PK_ASSERT_NO_ERROR()
     PK_ASSERT_N_EXTRA_ELEMENTS(1)
+    PyObject* item = vm->s_data.top();
     PK_PROTECTED(
-        PyObject* item = stack_item(vm, i);
-        PyObject* repr = vm->py_repr(item);
-        vm->s_data.push(repr);
+        item = vm->py_repr(item);
     )
+    vm->s_data.top() = item;
     return true;
 }
 

+ 3 - 0
tests/10_bytes.py

@@ -3,3 +3,6 @@ assert a.encode() == b'12345'
 
 assert b'\xff\xee' != b'1234'
 assert b'\xff\xee' == b'\xff\xee'
+
+a = '测试123'
+assert a == a.encode().decode()