From ea786811728f62db53293c60300c0b0417cd4435 Mon Sep 17 00:00:00 2001 From: blueloveTH Date: Wed, 28 Dec 2022 19:55:12 +0800 Subject: [PATCH] up Update analysis_options.yaml --- plugins/flutter/example/analysis_options.yaml | 11 - plugins/flutter/lib/common.dart | 8 + plugins/flutter/lib/jsonrpc.dart | 2 +- plugins/flutter/lib/no_web.dart | 178 +++++++++++++++++ plugins/flutter/lib/pocketpy.dart | 188 +----------------- plugins/flutter/src/pocketpy.h | 8 +- plugins/godot/godot-cpp | 2 +- src/error.h | 2 +- src/pocketpy.h | 2 +- src/str.h | 4 +- 10 files changed, 198 insertions(+), 207 deletions(-) create mode 100644 plugins/flutter/lib/common.dart create mode 100644 plugins/flutter/lib/no_web.dart diff --git a/plugins/flutter/example/analysis_options.yaml b/plugins/flutter/example/analysis_options.yaml index 61b6c4de..35c16ebe 100644 --- a/plugins/flutter/example/analysis_options.yaml +++ b/plugins/flutter/example/analysis_options.yaml @@ -1,14 +1,3 @@ -# This file configures the analyzer, which statically analyzes Dart code to -# check for errors, warnings, and lints. -# -# The issues identified by the analyzer are surfaced in the UI of Dart-enabled -# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be -# invoked from the command line by running `flutter analyze`. - -# The following line activates a set of recommended lints for Flutter apps, -# packages, and plugins designed to encourage good coding practices. -include: package:flutter_lints/flutter.yaml - linter: # The lint rules applied to this project can be customized in the # section below to disable rules from the `package:flutter_lints/flutter.yaml` diff --git a/plugins/flutter/lib/common.dart b/plugins/flutter/lib/common.dart new file mode 100644 index 00000000..e368e3d8 --- /dev/null +++ b/plugins/flutter/lib/common.dart @@ -0,0 +1,8 @@ +class PyOutput { + final String stdout; + final String stderr; + PyOutput(this.stdout, this.stderr); + + PyOutput.fromJson(Map json) + : stdout = json['stdout'], stderr = json['stderr']; +} diff --git a/plugins/flutter/lib/jsonrpc.dart b/plugins/flutter/lib/jsonrpc.dart index d8e1e5ad..38e583fb 100644 --- a/plugins/flutter/lib/jsonrpc.dart +++ b/plugins/flutter/lib/jsonrpc.dart @@ -4,7 +4,7 @@ import 'dart:async'; import 'dart:convert'; import 'dart:io'; -import 'package:pocketpy/pocketpy.dart'; +import 'no_web.dart' if (dart.library.html) 'web.dart'; class _JsonRpcError { final Map payload = {}; diff --git a/plugins/flutter/lib/no_web.dart b/plugins/flutter/lib/no_web.dart new file mode 100644 index 00000000..f8c06f6a --- /dev/null +++ b/plugins/flutter/lib/no_web.dart @@ -0,0 +1,178 @@ +// ignore_for_file: non_constant_identifier_names, prefer_typing_uninitialized_variables, constant_identifier_names, no_leading_underscores_for_local_identifiers + +import 'dart:convert' as cvt; +import 'dart:ffi' as ffi; +import 'dart:io'; +import 'package:ffi/ffi.dart'; +import 'common.dart'; + +class _Bindings +{ + static ffi.DynamicLibrary _load() { + String _libName = "pocketpy"; + if (Platform.isIOS) { + return ffi.DynamicLibrary.process(); + } + if (Platform.isAndroid || Platform.isLinux) { + return ffi.DynamicLibrary.open('lib$_libName.so'); + } + if (Platform.isWindows) { + return ffi.DynamicLibrary.open('$_libName.dll'); + } + throw UnsupportedError('Unknown platform: ${Platform.operatingSystem}'); + } + + static final _lib = _load(); + + static final pkpy_delete = _lib.lookupFunction("pkpy_delete"); + static final pkpy_new_repl = _lib.lookupFunction("pkpy_new_repl"); + static final pkpy_repl_input = _lib.lookupFunction line), int Function(ffi.Pointer r, ffi.Pointer line)>("pkpy_repl_input"); + static final pkpy_new_tvm = _lib.lookupFunction("pkpy_new_tvm"); + static final pkpy_tvm_exec_async = _lib.lookupFunction source), bool Function(ffi.Pointer vm, ffi.Pointer source)>("pkpy_tvm_exec_async"); + static final pkpy_tvm_get_state = _lib.lookupFunction("pkpy_tvm_get_state"); + static final pkpy_tvm_read_jsonrpc_request = _lib.lookupFunction Function(ffi.Pointer vm), ffi.Pointer Function(ffi.Pointer vm)>("pkpy_tvm_read_jsonrpc_request"); + static final pkpy_tvm_reset_state = _lib.lookupFunction("pkpy_tvm_reset_state"); + static final pkpy_tvm_terminate = _lib.lookupFunction("pkpy_tvm_terminate"); + static final pkpy_tvm_write_jsonrpc_response = _lib.lookupFunction value), void Function(ffi.Pointer vm, ffi.Pointer value)>("pkpy_tvm_write_jsonrpc_response"); + static final pkpy_new_vm = _lib.lookupFunction("pkpy_new_vm"); + static final pkpy_vm_add_module = _lib.lookupFunction name, ffi.Pointer source), bool Function(ffi.Pointer vm, ffi.Pointer name, ffi.Pointer source)>("pkpy_vm_add_module"); + static final pkpy_vm_eval = _lib.lookupFunction Function(ffi.Pointer vm, ffi.Pointer source), ffi.Pointer Function(ffi.Pointer vm, ffi.Pointer source)>("pkpy_vm_eval"); + static final pkpy_vm_exec = _lib.lookupFunction source), bool Function(ffi.Pointer vm, ffi.Pointer source)>("pkpy_vm_exec"); + static final pkpy_vm_get_global = _lib.lookupFunction Function(ffi.Pointer vm, ffi.Pointer name), ffi.Pointer Function(ffi.Pointer vm, ffi.Pointer name)>("pkpy_vm_get_global"); + static final pkpy_vm_read_output = _lib.lookupFunction Function(ffi.Pointer vm), ffi.Pointer Function(ffi.Pointer vm)>("pkpy_vm_read_output"); +} + + +class _Str { + static final Finalizer> finalizer = Finalizer((p) => calloc.free(p)); + + late final ffi.Pointer _p; + _Str(String s) { + _p = s.toNativeUtf8(); + finalizer.attach(this, _p); + } + + ffi.Pointer 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. Return `true` if there is no complie error. + bool add_module(String name, String source) + { + var ret = _Bindings.pkpy_vm_add_module(pointer, _Str(name).p, _Str(source).p); + return ret; + } + + /// 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. Return `true` if there is no compile error. + bool exec(String source) + { + var ret = _Bindings.pkpy_vm_exec(pointer, _Str(source).p); + return ret; + } + + /// 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. Return `true` if there is no compile error. + bool exec_async(String source) + { + var ret = _Bindings.pkpy_tvm_exec_async(pointer, _Str(source).p); + return ret; + } + + /// 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 { + late final ffi.Pointer pointer; + + REPL(VM vm) { + pointer = _Bindings.pkpy_new_repl(vm.pointer); + } + + void dispose() { + _Bindings.pkpy_delete(pointer); + } + + /// Input a source line to an interactive console. Return `0` if need more lines, `1` if execution happened, `2` if execution skipped (compile error or empty input). + int input(String line) + { + var ret = _Bindings.pkpy_repl_input(pointer, _Str(line).p); + return ret; + } + +} + diff --git a/plugins/flutter/lib/pocketpy.dart b/plugins/flutter/lib/pocketpy.dart index 31375942..f5792222 100644 --- a/plugins/flutter/lib/pocketpy.dart +++ b/plugins/flutter/lib/pocketpy.dart @@ -1,188 +1,4 @@ -// ignore_for_file: non_constant_identifier_names, prefer_typing_uninitialized_variables, constant_identifier_names, no_leading_underscores_for_local_identifiers - -import 'dart:convert' as cvt; -import 'dart:ffi' as ffi; -import 'dart:io'; -import 'package:ffi/ffi.dart'; +library pocketpy; export 'jsonrpc.dart'; - -class _Bindings -{ - static ffi.DynamicLibrary _load() { - String _libName = "pocketpy"; - if (Platform.isIOS) { - return ffi.DynamicLibrary.process(); - } - if (Platform.isAndroid || Platform.isLinux) { - return ffi.DynamicLibrary.open('lib$_libName.so'); - } - if (Platform.isWindows) { - return ffi.DynamicLibrary.open('$_libName.dll'); - } - throw UnsupportedError('Unknown platform: ${Platform.operatingSystem}'); - } - - static final _lib = _load(); - - static final pkpy_delete = _lib.lookupFunction("pkpy_delete"); - static final pkpy_new_repl = _lib.lookupFunction("pkpy_new_repl"); - static final pkpy_repl_input = _lib.lookupFunction line), int Function(ffi.Pointer r, ffi.Pointer line)>("pkpy_repl_input"); - static final pkpy_new_tvm = _lib.lookupFunction("pkpy_new_tvm"); - static final pkpy_tvm_exec_async = _lib.lookupFunction source), bool Function(ffi.Pointer vm, ffi.Pointer source)>("pkpy_tvm_exec_async"); - static final pkpy_tvm_get_state = _lib.lookupFunction("pkpy_tvm_get_state"); - static final pkpy_tvm_read_jsonrpc_request = _lib.lookupFunction Function(ffi.Pointer vm), ffi.Pointer Function(ffi.Pointer vm)>("pkpy_tvm_read_jsonrpc_request"); - static final pkpy_tvm_reset_state = _lib.lookupFunction("pkpy_tvm_reset_state"); - static final pkpy_tvm_terminate = _lib.lookupFunction("pkpy_tvm_terminate"); - static final pkpy_tvm_write_jsonrpc_response = _lib.lookupFunction value), void Function(ffi.Pointer vm, ffi.Pointer value)>("pkpy_tvm_write_jsonrpc_response"); - static final pkpy_new_vm = _lib.lookupFunction("pkpy_new_vm"); - static final pkpy_vm_add_module = _lib.lookupFunction name, ffi.Pointer source), bool Function(ffi.Pointer vm, ffi.Pointer name, ffi.Pointer source)>("pkpy_vm_add_module"); - static final pkpy_vm_eval = _lib.lookupFunction Function(ffi.Pointer vm, ffi.Pointer source), ffi.Pointer Function(ffi.Pointer vm, ffi.Pointer source)>("pkpy_vm_eval"); - static final pkpy_vm_exec = _lib.lookupFunction source), bool Function(ffi.Pointer vm, ffi.Pointer source)>("pkpy_vm_exec"); - static final pkpy_vm_get_global = _lib.lookupFunction Function(ffi.Pointer vm, ffi.Pointer name), ffi.Pointer Function(ffi.Pointer vm, ffi.Pointer name)>("pkpy_vm_get_global"); - static final pkpy_vm_read_output = _lib.lookupFunction Function(ffi.Pointer vm), ffi.Pointer Function(ffi.Pointer vm)>("pkpy_vm_read_output"); -} - - -class PyOutput { - final String stdout; - final String stderr; - PyOutput(this.stdout, this.stderr); - - PyOutput.fromJson(Map json) - : stdout = json['stdout'], stderr = json['stderr']; -} - -class _Str { - static final Finalizer> finalizer = Finalizer((p) => calloc.free(p)); - - late final ffi.Pointer _p; - _Str(String s) { - _p = s.toNativeUtf8(); - finalizer.attach(this, _p); - } - - ffi.Pointer 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. Return `true` if there is no complie error. - bool add_module(String name, String source) - { - var ret = _Bindings.pkpy_vm_add_module(pointer, _Str(name).p, _Str(source).p); - return ret; - } - - /// 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. Return `true` if there is no compile error. - bool exec(String source) - { - var ret = _Bindings.pkpy_vm_exec(pointer, _Str(source).p); - return ret; - } - - /// 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. Return `true` if there is no compile error. - bool exec_async(String source) - { - var ret = _Bindings.pkpy_tvm_exec_async(pointer, _Str(source).p); - return ret; - } - - /// 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 { - late final ffi.Pointer pointer; - - REPL(VM vm) { - pointer = _Bindings.pkpy_new_repl(vm.pointer); - } - - void dispose() { - _Bindings.pkpy_delete(pointer); - } - - /// Input a source line to an interactive console. Return `0` if need more lines, `1` if execution happened, `2` if execution skipped (compile error or empty input). - int input(String line) - { - var ret = _Bindings.pkpy_repl_input(pointer, _Str(line).p); - return ret; - } - -} - +export 'no_web.dart' if (dart.library.html) 'web.dart'; \ No newline at end of file diff --git a/plugins/flutter/src/pocketpy.h b/plugins/flutter/src/pocketpy.h index a096a75c..be4415c0 100644 --- a/plugins/flutter/src/pocketpy.h +++ b/plugins/flutter/src/pocketpy.h @@ -253,11 +253,11 @@ public: return _hash; } - int __to_u8_index(int index) const{ + int __to_u8_index(int64_t index) const{ utf8_lazy_init(); auto p = std::lower_bound(_u8_index->begin(), _u8_index->end(), index); if(*p != index) UNREACHABLE(); - return p - _u8_index->begin(); + return (int)(p - _u8_index->begin()); } int u8_length() const { @@ -2960,7 +2960,7 @@ struct SourceMetadata { } ss << " " << line << '\n'; if(cursor && line != "" && cursor >= pair.first && cursor <= pair.second){ - int column = cursor - pair.first - removedSpaces; + auto column = cursor - pair.first - removedSpaces; if(column >= 0){ ss << " " << std::string(column, ' ') << "^\n"; } @@ -6946,7 +6946,7 @@ void __addModuleRe(VM* vm){ vm->bindMethod("re.Match", "group", [](VM* vm, const pkpy::ArgList& args) { vm->__checkArgSize(args, 2, true); - _Int index = vm->PyInt_AS_C(args[1]); + int index = (int)vm->PyInt_AS_C(args[1]); const auto& vec = vm->PyTuple_AS_C(vm->getAttr(args[0], "_groups")); vm->normalizedIndex(index, vec.size()); return vec[index]; diff --git a/plugins/godot/godot-cpp b/plugins/godot/godot-cpp index d3e448cd..43c56123 160000 --- a/plugins/godot/godot-cpp +++ b/plugins/godot/godot-cpp @@ -1 +1 @@ -Subproject commit d3e448cdbca422c2c9af45b46d8371f66139e12e +Subproject commit 43c56123929e5a203a85412c4e30cb12d742f87c diff --git a/src/error.h b/src/error.h index 7994d1fd..9c0ce0bc 100644 --- a/src/error.h +++ b/src/error.h @@ -54,7 +54,7 @@ struct SourceMetadata { } ss << " " << line << '\n'; if(cursor && line != "" && cursor >= pair.first && cursor <= pair.second){ - int column = cursor - pair.first - removedSpaces; + auto column = cursor - pair.first - removedSpaces; if(column >= 0){ ss << " " << std::string(column, ' ') << "^\n"; } diff --git a/src/pocketpy.h b/src/pocketpy.h index 3ed554b6..e0d5594c 100644 --- a/src/pocketpy.h +++ b/src/pocketpy.h @@ -754,7 +754,7 @@ void __addModuleRe(VM* vm){ vm->bindMethod("re.Match", "group", [](VM* vm, const pkpy::ArgList& args) { vm->__checkArgSize(args, 2, true); - _Int index = vm->PyInt_AS_C(args[1]); + int index = (int)vm->PyInt_AS_C(args[1]); const auto& vec = vm->PyTuple_AS_C(vm->getAttr(args[0], "_groups")); vm->normalizedIndex(index, vec.size()); return vec[index]; diff --git a/src/str.h b/src/str.h index 30ec86bc..e77574ae 100644 --- a/src/str.h +++ b/src/str.h @@ -52,11 +52,11 @@ public: return _hash; } - int __to_u8_index(int index) const{ + int __to_u8_index(int64_t index) const{ utf8_lazy_init(); auto p = std::lower_bound(_u8_index->begin(), _u8_index->end(), index); if(*p != index) UNREACHABLE(); - return p - _u8_index->begin(); + return (int)(p - _u8_index->begin()); } int u8_length() const {