mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 11:30:18 +00:00
up
This commit is contained in:
parent
968ac29652
commit
2cc47b9574
@ -26,15 +26,7 @@ class _Bindings
|
|||||||
|
|
||||||
static final pkpy_delete = _lib.lookupFunction<ffi.Void Function(ffi.Pointer p), void Function(ffi.Pointer p)>("pkpy_delete");
|
static final pkpy_delete = _lib.lookupFunction<ffi.Void Function(ffi.Pointer p), void Function(ffi.Pointer p)>("pkpy_delete");
|
||||||
static final pkpy_new_repl = _lib.lookupFunction<ffi.Pointer Function(ffi.Pointer vm), ffi.Pointer Function(ffi.Pointer vm)>("pkpy_new_repl");
|
static final pkpy_new_repl = _lib.lookupFunction<ffi.Pointer Function(ffi.Pointer vm), ffi.Pointer Function(ffi.Pointer vm)>("pkpy_new_repl");
|
||||||
static final pkpy_repl_input = _lib.lookupFunction<ffi.Void Function(ffi.Pointer r, ffi.Pointer<Utf8> line), void Function(ffi.Pointer r, ffi.Pointer<Utf8> line)>("pkpy_repl_input");
|
static final pkpy_repl_input = _lib.lookupFunction<ffi.Int32 Function(ffi.Pointer r, ffi.Pointer<Utf8> line), int Function(ffi.Pointer r, ffi.Pointer<Utf8> line)>("pkpy_repl_input");
|
||||||
static final pkpy_repl_last_input_result = _lib.lookupFunction<ffi.Int32 Function(ffi.Pointer r), int Function(ffi.Pointer r)>("pkpy_repl_last_input_result");
|
|
||||||
static final pkpy_new_tvm = _lib.lookupFunction<ffi.Pointer Function(ffi.Bool use_stdio), ffi.Pointer Function(bool use_stdio)>("pkpy_new_tvm");
|
|
||||||
static final pkpy_tvm_exec_async = _lib.lookupFunction<ffi.Void Function(ffi.Pointer vm, ffi.Pointer<Utf8> source), void Function(ffi.Pointer vm, ffi.Pointer<Utf8> source)>("pkpy_tvm_exec_async");
|
|
||||||
static final pkpy_tvm_get_state = _lib.lookupFunction<ffi.Int32 Function(ffi.Pointer vm), int Function(ffi.Pointer vm)>("pkpy_tvm_get_state");
|
|
||||||
static final pkpy_tvm_read_jsonrpc_request = _lib.lookupFunction<ffi.Pointer<Utf8> Function(ffi.Pointer vm), ffi.Pointer<Utf8> Function(ffi.Pointer vm)>("pkpy_tvm_read_jsonrpc_request");
|
|
||||||
static final pkpy_tvm_reset_state = _lib.lookupFunction<ffi.Void Function(ffi.Pointer vm), void Function(ffi.Pointer vm)>("pkpy_tvm_reset_state");
|
|
||||||
static final pkpy_tvm_terminate = _lib.lookupFunction<ffi.Void Function(ffi.Pointer vm), void Function(ffi.Pointer vm)>("pkpy_tvm_terminate");
|
|
||||||
static final pkpy_tvm_write_jsonrpc_response = _lib.lookupFunction<ffi.Void Function(ffi.Pointer vm, ffi.Pointer<Utf8> value), void Function(ffi.Pointer vm, ffi.Pointer<Utf8> value)>("pkpy_tvm_write_jsonrpc_response");
|
|
||||||
static final pkpy_new_vm = _lib.lookupFunction<ffi.Pointer Function(ffi.Bool use_stdio), ffi.Pointer Function(bool use_stdio)>("pkpy_new_vm");
|
static final pkpy_new_vm = _lib.lookupFunction<ffi.Pointer Function(ffi.Bool use_stdio), ffi.Pointer Function(bool use_stdio)>("pkpy_new_vm");
|
||||||
static final pkpy_vm_add_module = _lib.lookupFunction<ffi.Void Function(ffi.Pointer vm, ffi.Pointer<Utf8> name, ffi.Pointer<Utf8> source), void Function(ffi.Pointer vm, ffi.Pointer<Utf8> name, ffi.Pointer<Utf8> source)>("pkpy_vm_add_module");
|
static final pkpy_vm_add_module = _lib.lookupFunction<ffi.Void Function(ffi.Pointer vm, ffi.Pointer<Utf8> name, ffi.Pointer<Utf8> source), void Function(ffi.Pointer vm, ffi.Pointer<Utf8> name, ffi.Pointer<Utf8> source)>("pkpy_vm_add_module");
|
||||||
static final pkpy_vm_eval = _lib.lookupFunction<ffi.Pointer<Utf8> Function(ffi.Pointer vm, ffi.Pointer<Utf8> source), ffi.Pointer<Utf8> Function(ffi.Pointer vm, ffi.Pointer<Utf8> source)>("pkpy_vm_eval");
|
static final pkpy_vm_eval = _lib.lookupFunction<ffi.Pointer<Utf8> Function(ffi.Pointer vm, ffi.Pointer<Utf8> source), ffi.Pointer<Utf8> Function(ffi.Pointer vm, ffi.Pointer<Utf8> source)>("pkpy_vm_eval");
|
||||||
@ -43,116 +35,6 @@ class _Bindings
|
|||||||
static final pkpy_vm_read_output = _lib.lookupFunction<ffi.Pointer<Utf8> Function(ffi.Pointer vm), ffi.Pointer<Utf8> Function(ffi.Pointer vm)>("pkpy_vm_read_output");
|
static final pkpy_vm_read_output = _lib.lookupFunction<ffi.Pointer<Utf8> Function(ffi.Pointer vm), ffi.Pointer<Utf8> Function(ffi.Pointer vm)>("pkpy_vm_read_output");
|
||||||
}
|
}
|
||||||
|
|
||||||
class _Str {
|
|
||||||
static final Finalizer<ffi.Pointer<Utf8>> finalizer = Finalizer((p) => malloc.free(p));
|
|
||||||
|
|
||||||
late final ffi.Pointer<Utf8> _p;
|
|
||||||
_Str(String s) {
|
|
||||||
_p = s.toNativeUtf8();
|
|
||||||
finalizer.attach(this, _p);
|
|
||||||
}
|
|
||||||
|
|
||||||
ffi.Pointer<Utf8> get p => _p;
|
|
||||||
}
|
|
||||||
class VM {
|
|
||||||
late final ffi.Pointer pointer;
|
|
||||||
|
|
||||||
VM() {
|
|
||||||
if (this is ThreadedVM) {
|
|
||||||
pointer = _Bindings.pkpy_new_tvm(false);
|
|
||||||
} else {
|
|
||||||
pointer = _Bindings.pkpy_new_vm(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void dispose() {
|
|
||||||
_Bindings.pkpy_delete(pointer);
|
|
||||||
}
|
|
||||||
|
|
||||||
PyOutput read_output() {
|
|
||||||
var _o = _Bindings.pkpy_vm_read_output(pointer);
|
|
||||||
String _j = _o.toDartString();
|
|
||||||
var ret = PyOutput.fromJson(cvt.jsonDecode(_j));
|
|
||||||
_Bindings.pkpy_delete(_o);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Add a source module into a virtual machine.
|
|
||||||
void add_module(String name, String source)
|
|
||||||
{
|
|
||||||
_Bindings.pkpy_vm_add_module(pointer, _Str(name).p, _Str(source).p);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Evaluate an expression. Return a json representing the result. If there is any error, return `nullptr`.
|
|
||||||
String? eval(String source)
|
|
||||||
{
|
|
||||||
var ret = _Bindings.pkpy_vm_eval(pointer, _Str(source).p);
|
|
||||||
if (ret == ffi.nullptr) return null;
|
|
||||||
String s = ret.toDartString();
|
|
||||||
_Bindings.pkpy_delete(ret);
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Run a given source on a virtual machine.
|
|
||||||
void exec(String source)
|
|
||||||
{
|
|
||||||
_Bindings.pkpy_vm_exec(pointer, _Str(source).p);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get a global variable of a virtual machine. Return a json representing the result. If the variable is not found, return `nullptr`.
|
|
||||||
String? get_global(String name)
|
|
||||||
{
|
|
||||||
var ret = _Bindings.pkpy_vm_get_global(pointer, _Str(name).p);
|
|
||||||
if (ret == ffi.nullptr) return null;
|
|
||||||
String s = ret.toDartString();
|
|
||||||
_Bindings.pkpy_delete(ret);
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
enum ThreadState { ready, running, suspended, finished }
|
|
||||||
|
|
||||||
class ThreadedVM extends VM {
|
|
||||||
ThreadState get state => ThreadState.values[_Bindings.pkpy_tvm_get_state(pointer)];
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// Run a given source on a threaded virtual machine. The excution will be started in a new thread.
|
|
||||||
void exec_async(String source)
|
|
||||||
{
|
|
||||||
_Bindings.pkpy_tvm_exec_async(pointer, _Str(source).p);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Read the current JSONRPC request from shared string buffer.
|
|
||||||
String? read_jsonrpc_request()
|
|
||||||
{
|
|
||||||
var ret = _Bindings.pkpy_tvm_read_jsonrpc_request(pointer);
|
|
||||||
if (ret == ffi.nullptr) return null;
|
|
||||||
String s = ret.toDartString();
|
|
||||||
_Bindings.pkpy_delete(ret);
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set the state of a threaded virtual machine to `THREAD_READY`. The current state should be `THREAD_FINISHED`.
|
|
||||||
void reset_state()
|
|
||||||
{
|
|
||||||
_Bindings.pkpy_tvm_reset_state(pointer);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Emit a KeyboardInterrupt signal to stop a running threaded virtual machine.
|
|
||||||
void terminate()
|
|
||||||
{
|
|
||||||
_Bindings.pkpy_tvm_terminate(pointer);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Write a JSONRPC response to shared string buffer.
|
|
||||||
void write_jsonrpc_response(String value)
|
|
||||||
{
|
|
||||||
_Bindings.pkpy_tvm_write_jsonrpc_response(pointer, _Str(value).p);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
class REPL {
|
class REPL {
|
||||||
late final ffi.Pointer pointer;
|
late final ffi.Pointer pointer;
|
||||||
@ -166,15 +48,9 @@ class REPL {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Input a source line to an interactive console.
|
/// Input a source line to an interactive console.
|
||||||
void input(String line)
|
int input(String line)
|
||||||
{
|
{
|
||||||
_Bindings.pkpy_repl_input(pointer, _Str(line).p);
|
var ret = _Bindings.pkpy_repl_input(pointer, _Str(line).p);
|
||||||
}
|
|
||||||
|
|
||||||
/// Check if the REPL needs more lines.
|
|
||||||
int last_input_result()
|
|
||||||
{
|
|
||||||
var ret = _Bindings.pkpy_repl_last_input_result(pointer);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,132 +3,20 @@ import 'dart:convert' as cvt;
|
|||||||
import 'package:js/js.dart';
|
import 'package:js/js.dart';
|
||||||
import 'common.dart';
|
import 'common.dart';
|
||||||
|
|
||||||
@JS()
|
|
||||||
@anonymous
|
|
||||||
class Opt {
|
|
||||||
external bool get async;
|
|
||||||
external factory Opt({bool async});
|
|
||||||
}
|
|
||||||
|
|
||||||
@JS("Module.ccall")
|
@JS("Module.ccall")
|
||||||
external dynamic ccall(String name, String? returnType, List<String> argTypes, List<dynamic> args, Opt opt);
|
external dynamic ccall(String name, String? returnType, List<String> argTypes, List<dynamic> args);
|
||||||
|
|
||||||
class _Bindings
|
class _Bindings
|
||||||
{
|
{
|
||||||
static final pkpy_delete = (dynamic p) => ccall("pkpy_delete", null, ["number"], [p], Opt(async: false));
|
static final pkpy_delete = (dynamic p) => ccall("pkpy_delete", null, ["number"], [p]);
|
||||||
static final pkpy_new_repl = (dynamic vm) => ccall("pkpy_new_repl", "number", ["number"], [vm], Opt(async: false));
|
static final pkpy_new_repl = (dynamic vm) => ccall("pkpy_new_repl", "number", ["number"], [vm]);
|
||||||
static final pkpy_repl_input = (dynamic r, String line) => ccall("pkpy_repl_input", null, ["number", "string"], [r, line], Opt(async: true));
|
static final pkpy_repl_input = (dynamic r, String line) => ccall("pkpy_repl_input", "number", ["number", "string"], [r, line]);
|
||||||
static final pkpy_repl_last_input_result = (dynamic r) => ccall("pkpy_repl_last_input_result", "number", ["number"], [r], Opt(async: false));
|
static final pkpy_new_vm = (bool use_stdio) => ccall("pkpy_new_vm", "number", ["boolean"], [use_stdio]);
|
||||||
static final pkpy_new_tvm = (bool use_stdio) => ccall("pkpy_new_tvm", "number", ["boolean"], [use_stdio], Opt(async: false));
|
static final pkpy_vm_add_module = (dynamic vm, String name, String source) => ccall("pkpy_vm_add_module", null, ["number", "string", "string"], [vm, name, source]);
|
||||||
static final pkpy_tvm_exec_async = (dynamic vm, String source) => ccall("pkpy_tvm_exec_async", null, ["number", "string"], [vm, source], Opt(async: true));
|
static final pkpy_vm_eval = (dynamic vm, String source) => ccall("pkpy_vm_eval", "string", ["number", "string"], [vm, source]);
|
||||||
static final pkpy_tvm_get_state = (dynamic vm) => ccall("pkpy_tvm_get_state", "number", ["number"], [vm], Opt(async: false));
|
static final pkpy_vm_exec = (dynamic vm, String source) => ccall("pkpy_vm_exec", null, ["number", "string"], [vm, source]);
|
||||||
static final pkpy_tvm_read_jsonrpc_request = (dynamic vm) => ccall("pkpy_tvm_read_jsonrpc_request", "string", ["number"], [vm], Opt(async: false));
|
static final pkpy_vm_get_global = (dynamic vm, String name) => ccall("pkpy_vm_get_global", "string", ["number", "string"], [vm, name]);
|
||||||
static final pkpy_tvm_reset_state = (dynamic vm) => ccall("pkpy_tvm_reset_state", null, ["number"], [vm], Opt(async: false));
|
static final pkpy_vm_read_output = (dynamic vm) => ccall("pkpy_vm_read_output", "string", ["number"], [vm]);
|
||||||
static final pkpy_tvm_terminate = (dynamic vm) => ccall("pkpy_tvm_terminate", null, ["number"], [vm], Opt(async: false));
|
|
||||||
static final pkpy_tvm_write_jsonrpc_response = (dynamic vm, String value) => ccall("pkpy_tvm_write_jsonrpc_response", null, ["number", "string"], [vm, value], Opt(async: false));
|
|
||||||
static final pkpy_new_vm = (bool use_stdio) => ccall("pkpy_new_vm", "number", ["boolean"], [use_stdio], Opt(async: false));
|
|
||||||
static final pkpy_vm_add_module = (dynamic vm, String name, String source) => ccall("pkpy_vm_add_module", null, ["number", "string", "string"], [vm, name, source], Opt(async: false));
|
|
||||||
static final pkpy_vm_eval = (dynamic vm, String source) => ccall("pkpy_vm_eval", "string", ["number", "string"], [vm, source], Opt(async: false));
|
|
||||||
static final pkpy_vm_exec = (dynamic vm, String source) => ccall("pkpy_vm_exec", null, ["number", "string"], [vm, source], Opt(async: false));
|
|
||||||
static final pkpy_vm_get_global = (dynamic vm, String name) => ccall("pkpy_vm_get_global", "string", ["number", "string"], [vm, name], Opt(async: false));
|
|
||||||
static final pkpy_vm_read_output = (dynamic vm) => ccall("pkpy_vm_read_output", "string", ["number"], [vm], Opt(async: false));
|
|
||||||
}
|
|
||||||
|
|
||||||
class VM {
|
|
||||||
late final dynamic pointer;
|
|
||||||
|
|
||||||
VM() {
|
|
||||||
if (this is ThreadedVM) {
|
|
||||||
pointer = _Bindings.pkpy_new_tvm(false);
|
|
||||||
} else {
|
|
||||||
pointer = _Bindings.pkpy_new_vm(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void dispose() {
|
|
||||||
_Bindings.pkpy_delete(pointer);
|
|
||||||
}
|
|
||||||
|
|
||||||
PyOutput read_output() {
|
|
||||||
var _o = _Bindings.pkpy_vm_read_output(pointer);
|
|
||||||
String _j = _o;
|
|
||||||
var ret = PyOutput.fromJson(cvt.jsonDecode(_j));
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Add a source module into a virtual machine.
|
|
||||||
void add_module(String name, String source)
|
|
||||||
{
|
|
||||||
_Bindings.pkpy_vm_add_module(pointer, name, source);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Evaluate an expression. Return a json representing the result. If there is any error, return `nullptr`.
|
|
||||||
String? eval(String source)
|
|
||||||
{
|
|
||||||
var ret = _Bindings.pkpy_vm_eval(pointer, source);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Run a given source on a virtual machine.
|
|
||||||
void exec(String source)
|
|
||||||
{
|
|
||||||
_Bindings.pkpy_vm_exec(pointer, source);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get a global variable of a virtual machine. Return a json representing the result. If the variable is not found, return `nullptr`.
|
|
||||||
String? get_global(String name)
|
|
||||||
{
|
|
||||||
var ret = _Bindings.pkpy_vm_get_global(pointer, name);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
enum ThreadState { ready, running, suspended, finished }
|
|
||||||
|
|
||||||
class ThreadedVM extends VM {
|
|
||||||
ThreadState get state => ThreadState.values[_Bindings.pkpy_tvm_get_state(pointer)];
|
|
||||||
|
|
||||||
|
|
||||||
@override
|
|
||||||
void dispose() {
|
|
||||||
terminate();
|
|
||||||
Future.delayed(Duration(milliseconds: 150)).then((_) => _Bindings.pkpy_delete(pointer));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// Run a given source on a threaded virtual machine. The excution will be started in a new thread.
|
|
||||||
void exec_async(String source)
|
|
||||||
{
|
|
||||||
_Bindings.pkpy_tvm_exec_async(pointer, source);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Read the current JSONRPC request from shared string buffer.
|
|
||||||
String? read_jsonrpc_request()
|
|
||||||
{
|
|
||||||
var ret = _Bindings.pkpy_tvm_read_jsonrpc_request(pointer);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set the state of a threaded virtual machine to `THREAD_READY`. The current state should be `THREAD_FINISHED`.
|
|
||||||
void reset_state()
|
|
||||||
{
|
|
||||||
_Bindings.pkpy_tvm_reset_state(pointer);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Emit a KeyboardInterrupt signal to stop a running threaded virtual machine.
|
|
||||||
void terminate()
|
|
||||||
{
|
|
||||||
_Bindings.pkpy_tvm_terminate(pointer);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Write a JSONRPC response to shared string buffer.
|
|
||||||
void write_jsonrpc_response(String value)
|
|
||||||
{
|
|
||||||
_Bindings.pkpy_tvm_write_jsonrpc_response(pointer, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class REPL {
|
class REPL {
|
||||||
@ -143,15 +31,9 @@ class REPL {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Input a source line to an interactive console.
|
/// Input a source line to an interactive console.
|
||||||
void input(String line)
|
int input(String line)
|
||||||
{
|
{
|
||||||
_Bindings.pkpy_repl_input(pointer, line);
|
var ret = _Bindings.pkpy_repl_input(pointer, line);
|
||||||
}
|
|
||||||
|
|
||||||
/// Check if the REPL needs more lines.
|
|
||||||
int last_input_result()
|
|
||||||
{
|
|
||||||
var ret = _Bindings.pkpy_repl_last_input_result(pointer);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1879,20 +1879,16 @@ namespace pkpy{
|
|||||||
}
|
}
|
||||||
|
|
||||||
shared_ptr& operator=(const shared_ptr& other) {
|
shared_ptr& operator=(const shared_ptr& other) {
|
||||||
if (this != &other) {
|
_dec_counter();
|
||||||
_dec_counter();
|
counter = other.counter;
|
||||||
counter = other.counter;
|
_inc_counter();
|
||||||
_inc_counter();
|
|
||||||
}
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_ptr& operator=(shared_ptr&& other) noexcept {
|
shared_ptr& operator=(shared_ptr&& other) noexcept {
|
||||||
if (this != &other) {
|
_dec_counter();
|
||||||
_dec_counter();
|
counter = other.counter;
|
||||||
counter = other.counter;
|
other.counter = nullptr;
|
||||||
other.counter = nullptr;
|
|
||||||
}
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2161,12 +2157,12 @@ public:
|
|||||||
typedef emhash8::HashMap<_Str, PyVar> PyVarDict;
|
typedef emhash8::HashMap<_Str, PyVar> PyVarDict;
|
||||||
|
|
||||||
namespace pkpy {
|
namespace pkpy {
|
||||||
const uint8_t MAX_POOLING_N = 10;
|
const int MAX_POOLING_N = 10;
|
||||||
static thread_local std::vector<PyVar*>* _poolArgList = new std::vector<PyVar*>[MAX_POOLING_N];
|
static thread_local std::vector<PyVar*>* _poolArgList = new std::vector<PyVar*>[MAX_POOLING_N];
|
||||||
|
|
||||||
class ArgList {
|
class ArgList {
|
||||||
PyVar* _args;
|
PyVar* _args;
|
||||||
uint8_t _size;
|
int _size;
|
||||||
|
|
||||||
void __tryAlloc(size_t n){
|
void __tryAlloc(size_t n){
|
||||||
if(n == 0){
|
if(n == 0){
|
||||||
@ -2174,7 +2170,6 @@ namespace pkpy {
|
|||||||
this->_size = 0;
|
this->_size = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(n > 255) UNREACHABLE();
|
|
||||||
if(n >= MAX_POOLING_N || _poolArgList[n].empty()){
|
if(n >= MAX_POOLING_N || _poolArgList[n].empty()){
|
||||||
this->_args = new PyVar[n];
|
this->_args = new PyVar[n];
|
||||||
this->_size = n;
|
this->_size = n;
|
||||||
@ -2190,7 +2185,7 @@ namespace pkpy {
|
|||||||
if(_size >= MAX_POOLING_N || _poolArgList[_size].size() > 32){
|
if(_size >= MAX_POOLING_N || _poolArgList[_size].size() > 32){
|
||||||
delete[] _args;
|
delete[] _args;
|
||||||
}else{
|
}else{
|
||||||
for(uint8_t i = 0; i < _size; i++) _args[i].reset();
|
for(int i = 0; i < _size; i++) _args[i].reset();
|
||||||
_poolArgList[_size].push_back(_args);
|
_poolArgList[_size].push_back(_args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2202,7 +2197,7 @@ namespace pkpy {
|
|||||||
|
|
||||||
ArgList(const ArgList& other){
|
ArgList(const ArgList& other){
|
||||||
__tryAlloc(other._size);
|
__tryAlloc(other._size);
|
||||||
for(uint8_t i=0; i<_size; i++) _args[i] = other._args[i];
|
for(int i=0; i<_size; i++) _args[i] = other._args[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
ArgList(ArgList&& other) noexcept {
|
ArgList(ArgList&& other) noexcept {
|
||||||
@ -2214,39 +2209,36 @@ namespace pkpy {
|
|||||||
|
|
||||||
ArgList(PyVarList&& other) noexcept {
|
ArgList(PyVarList&& other) noexcept {
|
||||||
__tryAlloc(other.size());
|
__tryAlloc(other.size());
|
||||||
for(uint8_t i=0; i<_size; i++){
|
for(int i=0; i<_size; i++){
|
||||||
_args[i] = std::move(other[i]);
|
_args[i] = std::move(other[i]);
|
||||||
}
|
}
|
||||||
other.clear();
|
other.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
PyVar& operator[](uint8_t i){ return _args[i]; }
|
PyVar& operator[](int i){ return _args[i]; }
|
||||||
const PyVar& operator[](uint8_t i) const { return _args[i]; }
|
const PyVar& operator[](int i) const { return _args[i]; }
|
||||||
|
|
||||||
// overload = for &&
|
|
||||||
ArgList& operator=(ArgList&& other) noexcept {
|
ArgList& operator=(ArgList&& other) noexcept {
|
||||||
if(this != &other){
|
__tryRelease();
|
||||||
__tryRelease();
|
this->_args = other._args;
|
||||||
this->_args = other._args;
|
this->_size = other._size;
|
||||||
this->_size = other._size;
|
other._args = nullptr;
|
||||||
other._args = nullptr;
|
other._size = 0;
|
||||||
other._size = 0;
|
|
||||||
}
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline uint8_t size() const { return _size; }
|
inline int size() const { return _size; }
|
||||||
|
|
||||||
PyVarList toList() const {
|
PyVarList toList() const {
|
||||||
PyVarList ret(_size);
|
PyVarList ret(_size);
|
||||||
for(uint8_t i=0; i<_size; i++) ret[i] = _args[i];
|
for(int i=0; i<_size; i++) ret[i] = _args[i];
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void extend_self(const PyVar& self){
|
void extend_self(const PyVar& self){
|
||||||
static_assert(std::is_standard_layout_v<PyVar>);
|
static_assert(std::is_standard_layout_v<PyVar>);
|
||||||
PyVar* old_args = _args;
|
PyVar* old_args = _args;
|
||||||
uint8_t old_size = _size;
|
int old_size = _size;
|
||||||
__tryAlloc(old_size+1);
|
__tryAlloc(old_size+1);
|
||||||
_args[0] = self;
|
_args[0] = self;
|
||||||
if(old_size == 0) return;
|
if(old_size == 0) return;
|
||||||
@ -3734,8 +3726,8 @@ public:
|
|||||||
PyVar _module;
|
PyVar _module;
|
||||||
pkpy::shared_ptr<PyVarDict> _locals;
|
pkpy::shared_ptr<PyVarDict> _locals;
|
||||||
|
|
||||||
inline PyVarDict& f_locals(){ return *_locals; }
|
inline PyVarDict& f_locals() noexcept { return *_locals; }
|
||||||
inline PyVarDict& f_globals(){ return _module->attribs; }
|
inline PyVarDict& f_globals() noexcept { return _module->attribs; }
|
||||||
|
|
||||||
Frame(const _Code code, PyVar _module, pkpy::shared_ptr<PyVarDict> _locals)
|
Frame(const _Code code, PyVar _module, pkpy::shared_ptr<PyVarDict> _locals)
|
||||||
: code(code), _module(_module), _locals(_locals) {
|
: code(code), _module(_module), _locals(_locals) {
|
||||||
@ -3823,12 +3815,6 @@ public:
|
|||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
PyVarList pop_n_values_reversed_unlimited(VM* vm, int n){
|
|
||||||
PyVarList v(n);
|
|
||||||
for(int i=n-1; i>=0; i--) v[i] = pop_value(vm);
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
pkpy::ArgList pop_n_reversed(int n){
|
pkpy::ArgList pop_n_reversed(int n){
|
||||||
pkpy::ArgList v(n);
|
pkpy::ArgList v(n);
|
||||||
for(int i=n-1; i>=0; i--) v[i] = pop();
|
for(int i=n-1; i>=0; i--) v[i] = pop();
|
||||||
@ -3855,7 +3841,6 @@ public:
|
|||||||
|
|
||||||
class VM {
|
class VM {
|
||||||
std::vector<PyVar> _small_integers; // [-5, 256]
|
std::vector<PyVar> _small_integers; // [-5, 256]
|
||||||
emhash8::HashMap<_Str, _Str> _lazy_modules; // lazy loaded modules
|
|
||||||
protected:
|
protected:
|
||||||
std::deque< std::unique_ptr<Frame> > callstack;
|
std::deque< std::unique_ptr<Frame> > callstack;
|
||||||
PyVar __py2py_call_signal;
|
PyVar __py2py_call_signal;
|
||||||
@ -4032,12 +4017,12 @@ protected:
|
|||||||
case OP_BUILD_LIST:
|
case OP_BUILD_LIST:
|
||||||
{
|
{
|
||||||
frame->push(PyList(
|
frame->push(PyList(
|
||||||
frame->pop_n_values_reversed_unlimited(this, byte.arg)
|
frame->pop_n_values_reversed(this, byte.arg).toList()
|
||||||
));
|
));
|
||||||
} break;
|
} break;
|
||||||
case OP_BUILD_MAP:
|
case OP_BUILD_MAP:
|
||||||
{
|
{
|
||||||
PyVarList items = frame->pop_n_values_reversed_unlimited(this, byte.arg*2);
|
pkpy::ArgList items = frame->pop_n_values_reversed(this, byte.arg*2);
|
||||||
PyVar obj = call(builtins->attribs["dict"]);
|
PyVar obj = call(builtins->attribs["dict"]);
|
||||||
for(int i=0; i<items.size(); i+=2){
|
for(int i=0; i<items.size(); i+=2){
|
||||||
call(obj, __setitem__, pkpy::twoArgs(items[i], items[i+1]));
|
call(obj, __setitem__, pkpy::twoArgs(items[i], items[i+1]));
|
||||||
@ -4047,7 +4032,7 @@ protected:
|
|||||||
case OP_BUILD_SET:
|
case OP_BUILD_SET:
|
||||||
{
|
{
|
||||||
PyVar list = PyList(
|
PyVar list = PyList(
|
||||||
frame->pop_n_values_reversed_unlimited(this, byte.arg)
|
frame->pop_n_values_reversed(this, byte.arg).toList()
|
||||||
);
|
);
|
||||||
PyVar obj = call(builtins->attribs["set"], pkpy::oneArg(list));
|
PyVar obj = call(builtins->attribs["set"], pkpy::oneArg(list));
|
||||||
frame->push(obj);
|
frame->push(obj);
|
||||||
@ -4143,7 +4128,7 @@ protected:
|
|||||||
}else{
|
}else{
|
||||||
const _Str& source = it2->second;
|
const _Str& source = it2->second;
|
||||||
_Code code = compile(source, name, EXEC_MODE);
|
_Code code = compile(source, name, EXEC_MODE);
|
||||||
PyVar _m = newModule(name);
|
PyVar _m = new_module(name);
|
||||||
_exec(code, _m, pkpy::make_shared<PyVarDict>());
|
_exec(code, _m, pkpy::make_shared<PyVarDict>());
|
||||||
frame->push(_m);
|
frame->push(_m);
|
||||||
_lazy_modules.erase(it2);
|
_lazy_modules.erase(it2);
|
||||||
@ -4173,6 +4158,7 @@ protected:
|
|||||||
public:
|
public:
|
||||||
PyVarDict _types;
|
PyVarDict _types;
|
||||||
PyVarDict _modules; // loaded modules
|
PyVarDict _modules; // loaded modules
|
||||||
|
emhash8::HashMap<_Str, _Str> _lazy_modules; // lazy loaded modules
|
||||||
PyVar None, True, False, Ellipsis;
|
PyVar None, True, False, Ellipsis;
|
||||||
|
|
||||||
bool use_stdio;
|
bool use_stdio;
|
||||||
@ -4222,8 +4208,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
const PyVar& asBool(const PyVar& obj){
|
const PyVar& asBool(const PyVar& obj){
|
||||||
if(obj == None) return False;
|
|
||||||
if(obj->is_type(_tp_bool)) return obj;
|
if(obj->is_type(_tp_bool)) return obj;
|
||||||
|
if(obj == None) return False;
|
||||||
if(obj->is_type(_tp_int)) return PyBool(PyInt_AS_C(obj) != 0);
|
if(obj->is_type(_tp_int)) return PyBool(PyInt_AS_C(obj) != 0);
|
||||||
if(obj->is_type(_tp_float)) return PyBool(PyFloat_AS_C(obj) != 0.0);
|
if(obj->is_type(_tp_float)) return PyBool(PyFloat_AS_C(obj) != 0.0);
|
||||||
PyVarOrNull len_fn = getattr(obj, __len__, false);
|
PyVarOrNull len_fn = getattr(obj, __len__, false);
|
||||||
@ -4431,17 +4417,13 @@ public:
|
|||||||
return new_object(T::_tp(this), T(std::forward<Args>(args)...));
|
return new_object(T::_tp(this), T(std::forward<Args>(args)...));
|
||||||
}
|
}
|
||||||
|
|
||||||
PyVar newModule(_Str name) {
|
PyVar new_module(_Str name) {
|
||||||
PyVar obj = new_object(_tp_module, (i64)-2);
|
PyVar obj = new_object(_tp_module, DUMMY_VAL);
|
||||||
setattr(obj, __name__, PyStr(name));
|
setattr(obj, __name__, PyStr(name));
|
||||||
_modules[name] = obj;
|
_modules[name] = obj;
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
void addLazyModule(_Str name, _Str source){
|
|
||||||
_lazy_modules[name] = source;
|
|
||||||
}
|
|
||||||
|
|
||||||
PyVarOrNull getattr(const PyVar& obj, const _Str& name, bool throw_err=true) {
|
PyVarOrNull getattr(const PyVar& obj, const _Str& name, bool throw_err=true) {
|
||||||
PyVarDict::iterator it;
|
PyVarDict::iterator it;
|
||||||
PyObject* cls;
|
PyObject* cls;
|
||||||
@ -4481,15 +4463,11 @@ public:
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
void setattr(PyObject* obj, const _Str& name, T&& value) {
|
|
||||||
while(obj->is_type(_tp_super)) obj = ((Py_<PyVar>*)obj)->_valueT.get();
|
|
||||||
obj->attribs[name] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline void setattr(PyVar& obj, const _Str& name, T&& value) {
|
inline void setattr(PyVar& obj, const _Str& name, T&& value) {
|
||||||
setattr(obj.get(), name, value);
|
PyObject* p = obj.get();
|
||||||
|
while(p->is_type(_tp_super)) p = ((Py_<PyVar>*)p)->_valueT.get();
|
||||||
|
p->attribs[name] = std::forward<T>(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int ARGC>
|
template<int ARGC>
|
||||||
@ -4523,14 +4501,6 @@ public:
|
|||||||
bindFunc<ARGC>(builtins, funcName, fn);
|
bindFunc<ARGC>(builtins, funcName, fn);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool is_int_or_float(const PyVar& obj) const{
|
|
||||||
return obj->is_type(_tp_int) || obj->is_type(_tp_float);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool is_int_or_float(const PyVar& obj1, const PyVar& obj2) const{
|
|
||||||
return is_int_or_float(obj1) && is_int_or_float(obj2);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline f64 num_to_float(const PyVar& obj){
|
inline f64 num_to_float(const PyVar& obj){
|
||||||
if (obj->is_type(_tp_int)){
|
if (obj->is_type(_tp_int)){
|
||||||
return (f64)PyInt_AS_C(obj);
|
return (f64)PyInt_AS_C(obj);
|
||||||
@ -4693,8 +4663,8 @@ public:
|
|||||||
this->Ellipsis = new_object(_types["ellipsis"], DUMMY_VAL);
|
this->Ellipsis = new_object(_types["ellipsis"], DUMMY_VAL);
|
||||||
this->True = new_object(_tp_bool, true);
|
this->True = new_object(_tp_bool, true);
|
||||||
this->False = new_object(_tp_bool, false);
|
this->False = new_object(_tp_bool, false);
|
||||||
this->builtins = newModule("builtins");
|
this->builtins = new_module("builtins");
|
||||||
this->_main = newModule("__main__");
|
this->_main = new_module("__main__");
|
||||||
|
|
||||||
setattr(_tp_type, __base__, _tp_object);
|
setattr(_tp_type, __base__, _tp_object);
|
||||||
_tp_type->_type = _tp_type;
|
_tp_type->_type = _tp_type;
|
||||||
@ -5018,6 +4988,7 @@ public:
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
buff.push_back(c);
|
buff.push_back(c);
|
||||||
|
continue;
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -6036,16 +6007,13 @@ __NOT_ENOUGH_LINES:
|
|||||||
}
|
}
|
||||||
|
|
||||||
try{
|
try{
|
||||||
vm->compile(line, "<stdin>", mode);
|
vm->exec(line, "<stdin>", mode);
|
||||||
}catch(NeedMoreLines& ne){
|
}catch(NeedMoreLines& ne){
|
||||||
buffer += line;
|
buffer += line;
|
||||||
buffer += '\n';
|
buffer += '\n';
|
||||||
need_more_lines = ne.isClassDef ? 3 : 2;
|
need_more_lines = ne.isClassDef ? 3 : 2;
|
||||||
if (need_more_lines) return NEED_MORE_LINES;
|
if (need_more_lines) return NEED_MORE_LINES;
|
||||||
}catch(...){
|
|
||||||
// do nothing
|
|
||||||
}
|
}
|
||||||
vm->exec(line, "<stdin>", mode);
|
|
||||||
return EXEC_STARTED;
|
return EXEC_STARTED;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -6063,21 +6031,23 @@ _Code VM::compile(_Str source, _Str filename, CompileMode mode) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define BIND_NUM_ARITH_OPT(name, op) \
|
#define BIND_NUM_ARITH_OPT(name, op) \
|
||||||
_vm->bindMethodMulti<1>({"int","float"}, #name, [](VM* vm, const pkpy::ArgList& args){ \
|
_vm->bindMethodMulti<1>({"int","float"}, #name, [](VM* vm, const pkpy::ArgList& args){ \
|
||||||
if(args[0]->is_type(vm->_tp_int) && args[1]->is_type(vm->_tp_int)){ \
|
if(args[0]->is_type(vm->_tp_int) && args[1]->is_type(vm->_tp_int)){ \
|
||||||
return vm->PyInt(vm->PyInt_AS_C(args[0]) op vm->PyInt_AS_C(args[1])); \
|
return vm->PyInt(vm->PyInt_AS_C(args[0]) op vm->PyInt_AS_C(args[1])); \
|
||||||
}else{ \
|
}else{ \
|
||||||
return vm->PyFloat(vm->num_to_float(args[0]) op vm->num_to_float(args[1])); \
|
return vm->PyFloat(vm->num_to_float(args[0]) op vm->num_to_float(args[1])); \
|
||||||
} \
|
} \
|
||||||
});
|
});
|
||||||
|
|
||||||
#define BIND_NUM_LOGICAL_OPT(name, op, is_eq) \
|
#define BIND_NUM_LOGICAL_OPT(name, op, is_eq) \
|
||||||
_vm->bindMethodMulti<1>({"int","float"}, #name, [](VM* vm, const pkpy::ArgList& args){ \
|
_vm->bindMethodMulti<1>({"int","float"}, #name, [](VM* vm, const pkpy::ArgList& args){ \
|
||||||
if(!vm->is_int_or_float(args[0], args[1])){ \
|
bool _0 = args[0]->is_type(vm->_tp_int) || args[0]->is_type(vm->_tp_float); \
|
||||||
|
bool _1 = args[1]->is_type(vm->_tp_int) || args[1]->is_type(vm->_tp_float); \
|
||||||
|
if(!_0 || !_1){ \
|
||||||
if constexpr(is_eq) return vm->PyBool(args[0] == args[1]); \
|
if constexpr(is_eq) return vm->PyBool(args[0] == args[1]); \
|
||||||
vm->typeError("unsupported operand type(s) for " #op ); \
|
vm->typeError("unsupported operand type(s) for " #op ); \
|
||||||
} \
|
} \
|
||||||
return vm->PyBool(vm->num_to_float(args[0]) op vm->num_to_float(args[1])); \
|
return vm->PyBool(vm->num_to_float(args[0]) op vm->num_to_float(args[1])); \
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@ -6107,14 +6077,12 @@ void __initializeBuiltinFunctions(VM* _vm) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
_vm->bindBuiltinFunc<1>("eval", [](VM* vm, const pkpy::ArgList& args) {
|
_vm->bindBuiltinFunc<1>("eval", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
const _Str& expr = vm->PyStr_AS_C(args[0]);
|
_Code code = vm->compile(vm->PyStr_AS_C(args[0]), "<eval>", EVAL_MODE);
|
||||||
_Code code = vm->compile(expr, "<eval>", EVAL_MODE);
|
|
||||||
return vm->_exec(code, vm->top_frame()->_module, vm->top_frame()->_locals);
|
return vm->_exec(code, vm->top_frame()->_module, vm->top_frame()->_locals);
|
||||||
});
|
});
|
||||||
|
|
||||||
_vm->bindBuiltinFunc<1>("exec", [](VM* vm, const pkpy::ArgList& args) {
|
_vm->bindBuiltinFunc<1>("exec", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
const _Str& expr = vm->PyStr_AS_C(args[0]);
|
_Code code = vm->compile(vm->PyStr_AS_C(args[0]), "<exec>", EXEC_MODE);
|
||||||
_Code code = vm->compile(expr, "<exec>", EXEC_MODE);
|
|
||||||
vm->_exec(code, vm->top_frame()->_module, vm->top_frame()->_locals);
|
vm->_exec(code, vm->top_frame()->_module, vm->top_frame()->_locals);
|
||||||
return vm->None;
|
return vm->None;
|
||||||
});
|
});
|
||||||
@ -6135,22 +6103,19 @@ void __initializeBuiltinFunctions(VM* _vm) {
|
|||||||
return vm->PyInt((i64)s[0]);
|
return vm->PyInt((i64)s[0]);
|
||||||
});
|
});
|
||||||
|
|
||||||
_vm->bindBuiltinFunc<0>("globals", [](VM* vm, const pkpy::ArgList& args) {
|
_vm->bindBuiltinFunc<2>("hasattr", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
const auto& d = vm->top_frame()->f_globals();
|
return vm->PyBool(vm->getattr(args[0], vm->PyStr_AS_C(args[1]), false) != nullptr);
|
||||||
PyVar obj = vm->call(vm->builtins->attribs["dict"]);
|
|
||||||
for (const auto& [k, v] : d) {
|
|
||||||
vm->call(obj, __setitem__, pkpy::twoArgs(vm->PyStr(k), v));
|
|
||||||
}
|
|
||||||
return obj;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
_vm->bindBuiltinFunc<0>("locals", [](VM* vm, const pkpy::ArgList& args) {
|
_vm->bindBuiltinFunc<3>("setattr", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
const auto& d = vm->top_frame()->f_locals();
|
PyVar obj = args[0];
|
||||||
PyVar obj = vm->call(vm->builtins->attribs["dict"]);
|
vm->setattr(obj, vm->PyStr_AS_C(args[1]), args[2]);
|
||||||
for (const auto& [k, v] : d) {
|
return vm->None;
|
||||||
vm->call(obj, __setitem__, pkpy::twoArgs(vm->PyStr(k), v));
|
});
|
||||||
}
|
|
||||||
return obj;
|
_vm->bindBuiltinFunc<2>("getattr", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
|
_Str name = vm->PyStr_AS_C(args[1]);
|
||||||
|
return vm->getattr(args[0], name);
|
||||||
});
|
});
|
||||||
|
|
||||||
_vm->bindBuiltinFunc<1>("hex", [](VM* vm, const pkpy::ArgList& args) {
|
_vm->bindBuiltinFunc<1>("hex", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
@ -6554,7 +6519,7 @@ void __initializeBuiltinFunctions(VM* _vm) {
|
|||||||
|
|
||||||
|
|
||||||
void __addModuleTime(VM* vm){
|
void __addModuleTime(VM* vm){
|
||||||
PyVar mod = vm->newModule("time");
|
PyVar mod = vm->new_module("time");
|
||||||
vm->bindFunc<0>(mod, "time", [](VM* vm, const pkpy::ArgList& args) {
|
vm->bindFunc<0>(mod, "time", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
auto now = std::chrono::high_resolution_clock::now();
|
auto now = std::chrono::high_resolution_clock::now();
|
||||||
return vm->PyFloat(std::chrono::duration_cast<std::chrono::microseconds>(now.time_since_epoch()).count() / 1000000.0);
|
return vm->PyFloat(std::chrono::duration_cast<std::chrono::microseconds>(now.time_since_epoch()).count() / 1000000.0);
|
||||||
@ -6562,7 +6527,7 @@ void __addModuleTime(VM* vm){
|
|||||||
}
|
}
|
||||||
|
|
||||||
void __addModuleSys(VM* vm){
|
void __addModuleSys(VM* vm){
|
||||||
PyVar mod = vm->newModule("sys");
|
PyVar mod = vm->new_module("sys");
|
||||||
vm->bindFunc<1>(mod, "getrefcount", [](VM* vm, const pkpy::ArgList& args) {
|
vm->bindFunc<1>(mod, "getrefcount", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
return vm->PyInt(args[0].use_count());
|
return vm->PyInt(args[0].use_count());
|
||||||
});
|
});
|
||||||
@ -6580,7 +6545,7 @@ void __addModuleSys(VM* vm){
|
|||||||
}
|
}
|
||||||
|
|
||||||
void __addModuleJson(VM* vm){
|
void __addModuleJson(VM* vm){
|
||||||
PyVar mod = vm->newModule("json");
|
PyVar mod = vm->new_module("json");
|
||||||
vm->bindFunc<1>(mod, "loads", [](VM* vm, const pkpy::ArgList& args) {
|
vm->bindFunc<1>(mod, "loads", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
const _Str& expr = vm->PyStr_AS_C(args[0]);
|
const _Str& expr = vm->PyStr_AS_C(args[0]);
|
||||||
_Code code = vm->compile(expr, "<json>", JSON_MODE);
|
_Code code = vm->compile(expr, "<json>", JSON_MODE);
|
||||||
@ -6593,7 +6558,7 @@ void __addModuleJson(VM* vm){
|
|||||||
}
|
}
|
||||||
|
|
||||||
void __addModuleMath(VM* vm){
|
void __addModuleMath(VM* vm){
|
||||||
PyVar mod = vm->newModule("math");
|
PyVar mod = vm->new_module("math");
|
||||||
vm->setattr(mod, "pi", vm->PyFloat(3.1415926535897932384));
|
vm->setattr(mod, "pi", vm->PyFloat(3.1415926535897932384));
|
||||||
vm->setattr(mod, "e" , vm->PyFloat(2.7182818284590452354));
|
vm->setattr(mod, "e" , vm->PyFloat(2.7182818284590452354));
|
||||||
|
|
||||||
@ -6692,7 +6657,7 @@ PyVar __regex_search(const _Str& pattern, const _Str& string, bool fromStart, VM
|
|||||||
};
|
};
|
||||||
|
|
||||||
void __addModuleRe(VM* vm){
|
void __addModuleRe(VM* vm){
|
||||||
PyVar mod = vm->newModule("re");
|
PyVar mod = vm->new_module("re");
|
||||||
ReMatch::_bind(vm);
|
ReMatch::_bind(vm);
|
||||||
|
|
||||||
vm->bindFunc<2>(mod, "match", [](VM* vm, const pkpy::ArgList& args) {
|
vm->bindFunc<2>(mod, "match", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
@ -6828,7 +6793,7 @@ extern "C" {
|
|||||||
__EXPORT
|
__EXPORT
|
||||||
/// Add a source module into a virtual machine.
|
/// Add a source module into a virtual machine.
|
||||||
void pkpy_vm_add_module(VM* vm, const char* name, const char* source){
|
void pkpy_vm_add_module(VM* vm, const char* name, const char* source){
|
||||||
vm->addLazyModule(name, source);
|
vm->_lazy_modules[name] = source;
|
||||||
}
|
}
|
||||||
|
|
||||||
void __vm_init(VM* vm){
|
void __vm_init(VM* vm){
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 4bbbb85979391fd8b1aa349ad81d6527db069ab2
|
Subproject commit 67715ff019df22dc7a99a73352515eb7106b33b9
|
Loading…
x
Reference in New Issue
Block a user