Reset JavaScript port to upstream state
This commit is contained in:
parent
4ffae4c588
commit
b3f0b9244e
@ -1,109 +1,29 @@
|
||||
# customizations for lvgl
|
||||
WASM_FILE_API = 1
|
||||
FROZEN_DIR ?= modules
|
||||
include ../../py/mkenv.mk
|
||||
|
||||
CROSS = 0
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
QSTR_DEFS = qstrdefsport.h
|
||||
|
||||
include $(TOP)/py/py.mk
|
||||
|
||||
CC = emcc -g4
|
||||
LD = emcc -g4
|
||||
|
||||
INC += -I.
|
||||
INC += -I$(TOP)
|
||||
INC += -I$(BUILD)
|
||||
|
||||
|
||||
LDFLAGS ?= -m32 -Wl,--gc-sections
|
||||
CFLAGS ?= -m32
|
||||
|
||||
#default debug options for browser debugger
|
||||
JSFLAGS ?= --source-map-base http://localhost:8000
|
||||
|
||||
#Debugging/Optimization
|
||||
ifeq ($(DEBUG), 1)
|
||||
CFLAGS += -O0 -g4
|
||||
else
|
||||
CFLAGS += -Oz -g0 -DNDEBUG
|
||||
endif
|
||||
|
||||
CFLAGS += -Wall -Werror $(INC) -std=gnu11 $(COPT)
|
||||
CFLAGS += -fdata-sections -ffunction-sections
|
||||
CFLAGS += $(CFLAGS_MOD)
|
||||
|
||||
JSFLAGS += -s USE_SDL=2 -s WASM=0
|
||||
JSFLAGS += --memory-init-file 0 --js-library library.js
|
||||
JSFLAGS += -s EXTRA_EXPORTED_RUNTIME_METHODS="['ccall', 'cwrap']"
|
||||
JSFLAGS += -s EXPORTED_FUNCTIONS="['_mp_js_init', '_mp_js_init_repl', '_mp_js_do_str', '_mp_js_process_char', '_mp_hal_get_interrupt_char', '_mp_keyboard_interrupt', '_mp_handle_pending' ]"
|
||||
CPP = clang -E
|
||||
|
||||
ifdef EMSCRIPTEN
|
||||
# only for profiling, remove -s EMTERPRETIFY_ADVISE=1 when your EMTERPRETIFY_WHITELIST is ok
|
||||
# not using an emterpreting list *is* bad and will lead to poor performance and huge binary.
|
||||
ifdef ASYNC
|
||||
CFLAGS += -D__EMTERPRETER__=1
|
||||
CFLAGS += -s EMTERPRETIFY=1 -s EMTERPRETIFY_ASYNC=1 -s 'EMTERPRETIFY_FILE="micropython.binary"'
|
||||
CFLAGS += -s EMTERPRETIFY_SYNCLIST='["_mp_execute_bytecode"]' -s EMTERPRETIFY_ADVISE=1
|
||||
endif
|
||||
|
||||
#check if not using emscripten-upstream branch
|
||||
ifeq (,$(findstring upstream/bin, $(EMMAKEN_COMPILER)))
|
||||
JSFLAGS += -s "BINARYEN_TRAP_MODE='clamp'"
|
||||
LDFLAGS += -Wl,-Map=$@.map,--cref
|
||||
endif
|
||||
|
||||
CC = emcc $(JSFLAGS)
|
||||
LD = emcc $(JSFLAGS)
|
||||
CPP = clang -E -undef -D__CPP__ -D__EMSCRIPTEN__ -U__STDC_VERSION__
|
||||
CPP += --sysroot $(EMSCRIPTEN)/system
|
||||
CPP += -include $(BUILD)/clang_predefs.h
|
||||
CPP += $(addprefix -isystem, $(shell env LC_ALL=C $(CC) $(CFLAGS_EXTRA) -E -x c++ /dev/null -v 2>&1 |sed -e '/^\#include <...>/,/^End of search/{ //!b };d'))
|
||||
else
|
||||
ifdef CLANG
|
||||
CC=clang
|
||||
CPP=clang -E -D__CPP__
|
||||
else
|
||||
CC = gcc
|
||||
CPP = gcc -E -D__CPP__
|
||||
endif
|
||||
CPP += -isystem $(EMSCRIPTEN)/system/include/libc -cxx-isystem $(EMSCRIPTEN)/system/include/libcxx
|
||||
endif
|
||||
|
||||
CFLAGS = -m32 -Wall -Werror $(INC) -std=c99 $(COPT)
|
||||
LDFLAGS = -m32 -Wl,-Map=$@.map,--cref -Wl,--gc-sections
|
||||
|
||||
|
||||
SRC_LIB = $(addprefix lib/,\
|
||||
utils/interrupt_char.c \
|
||||
utils/stdout_helpers.c \
|
||||
utils/pyexec.c \
|
||||
mp-readline/readline.c \
|
||||
)
|
||||
|
||||
|
||||
|
||||
LIB_SRC_C = $(addprefix lib/,\
|
||||
lv_bindings/driver/SDL/SDL_monitor.c \
|
||||
lv_bindings/driver/SDL/SDL_mouse.c \
|
||||
lv_bindings/driver/SDL/modSDL.c \
|
||||
$(LIB_SRC_C_EXTRA) \
|
||||
timeutils/timeutils.c \
|
||||
)
|
||||
|
||||
SRC_C = \
|
||||
main.c \
|
||||
mphalport.c \
|
||||
modutime.c \
|
||||
|
||||
ifdef WASM_FILE_API
|
||||
SRC_C += file.c wasm_file_api.c
|
||||
endif
|
||||
|
||||
ifneq ($(FROZEN_DIR),)
|
||||
# To use frozen source modules, put your .py files in a subdirectory (eg scripts/)
|
||||
# and then invoke make with FROZEN_DIR=scripts (be sure to build from scratch).
|
||||
CFLAGS += -DMICROPY_MODULE_FROZEN_STR
|
||||
endif
|
||||
CFLAGS += -O0 -DNDEBUG
|
||||
CFLAGS += -fdata-sections -ffunction-sections
|
||||
|
||||
ifneq ($(FROZEN_MPY_DIR),)
|
||||
# To use frozen bytecode, put your .py files in a subdirectory (eg frozen/) and
|
||||
@ -112,22 +32,26 @@ CFLAGS += -DMICROPY_QSTR_EXTRA_POOL=mp_qstr_frozen_const_pool
|
||||
CFLAGS += -DMICROPY_MODULE_FROZEN_MPY
|
||||
endif
|
||||
|
||||
SRC_C += $(SRC_MOD)
|
||||
SRC_LIB = $(addprefix lib/,\
|
||||
utils/interrupt_char.c \
|
||||
utils/stdout_helpers.c \
|
||||
utils/pyexec.c \
|
||||
mp-readline/readline.c \
|
||||
)
|
||||
|
||||
SRC_QSTR += $(BUILD)/clang_predefs.h $(SRC_C) $(SRC_LIB) $(LIB_SRC_C)
|
||||
SRC_C = \
|
||||
main.c \
|
||||
mphalport.c \
|
||||
modutime.c \
|
||||
|
||||
SRC_QSTR += $(SRC_C)
|
||||
|
||||
OBJ =
|
||||
OBJ = $(PY_O)
|
||||
OBJ += $(addprefix $(BUILD)/, $(SRC_LIB:.c=.o))
|
||||
OBJ += $(addprefix $(BUILD)/, $(SRC_C:.c=.o))
|
||||
OBJ += $(addprefix $(BUILD)/, $(LIB_SRC_C:.c=.o))
|
||||
|
||||
$(BUILD)/clang_predefs.h:
|
||||
$(Q)mkdir -p $(dir $@)
|
||||
$(Q)emcc $(CFLAGS) $(CFLAGS_EXTRA) $(JSFLAGS) -E -x c /dev/null -dM > $@
|
||||
|
||||
# Create `clang_predefs.h` as soon as possible, using a Makefile trick
|
||||
|
||||
Makefile: $(BUILD)/clang_predefs.h
|
||||
JSFLAGS = -O0 -s EXPORTED_FUNCTIONS="['_mp_js_init', '_mp_js_init_repl', '_mp_js_do_str', '_mp_js_process_char', '_mp_hal_get_interrupt_char', '_mp_keyboard_interrupt']" -s EXTRA_EXPORTED_RUNTIME_METHODS="['ccall', 'cwrap']" -s "BINARYEN_TRAP_MODE='clamp'" --memory-init-file 0 --js-library library.js
|
||||
|
||||
all: $(BUILD)/micropython.js
|
||||
|
||||
@ -135,7 +59,6 @@ $(BUILD)/micropython.js: $(OBJ) library.js wrapper.js
|
||||
$(ECHO) "LINK $(BUILD)/firmware.js"
|
||||
$(Q)emcc $(LDFLAGS) -o $(BUILD)/firmware.js $(OBJ) $(JSFLAGS)
|
||||
cat wrapper.js $(BUILD)/firmware.js > $@
|
||||
cp $@ $(BUILD)/../lvgl_mp.js
|
||||
|
||||
min: $(BUILD)/micropython.js
|
||||
uglifyjs $< -c -o $(BUILD)/micropython.min.js
|
||||
|
||||
@ -1,178 +0,0 @@
|
||||
// ============================== FILE I/O (sync => bad) =================================
|
||||
window.urls = {"name":"webcache","id":-1, "index": "/index.html"}
|
||||
|
||||
|
||||
function awfull_get(url) {
|
||||
function updateProgress (oEvent) {
|
||||
if (oEvent.lengthComputable) {
|
||||
var percentComplete = oEvent.loaded / oEvent.total;
|
||||
} else {
|
||||
// Unable to compute progress information since the total size is unknown
|
||||
// on binary XHR
|
||||
}
|
||||
}
|
||||
|
||||
function transferFailed(evt) {
|
||||
console.log("awfull_get: An error occurred while transferring the file '"+window.currentTransfer+"'");
|
||||
window.currentTransferSize = -1 ;
|
||||
}
|
||||
|
||||
function transferCanceled(evt) {
|
||||
console.log("awfull_get: transfer '"+window.currentTransfer+"' has been canceled by the user.");
|
||||
window.currentTransferSize = -1 ;
|
||||
}
|
||||
|
||||
var oReq = new XMLHttpRequest();
|
||||
|
||||
function transferComplete(evt) {
|
||||
if (oReq.status==404){
|
||||
console.log("awfull_get: File not found : "+ url );
|
||||
window.currentTransferSize = -1 ;
|
||||
|
||||
} else {
|
||||
window.currentTransferSize = oReq.response.length;
|
||||
console.log("awfull_get: Transfer is complete saving : "+window.currentTransferSize);
|
||||
}
|
||||
}
|
||||
|
||||
oReq.overrideMimeType("text/plain; charset=x-user-defined");
|
||||
oReq.addEventListener("progress", updateProgress);
|
||||
oReq.addEventListener("load", transferComplete);
|
||||
oReq.addEventListener("error", transferFailed);
|
||||
oReq.addEventListener("abort", transferCanceled);
|
||||
oReq.open("GET",url ,false);
|
||||
oReq.send();
|
||||
return oReq.response
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
function wasm_file_open(url, cachefile){
|
||||
var dirpath = ""
|
||||
if ( url == cachefile ) {
|
||||
//we need to build the target path, it could be a module import.
|
||||
|
||||
//transform to relative path to /
|
||||
while (cachefile.startswith("/"))
|
||||
cachefile = cachefile.substring(1)
|
||||
|
||||
while (url.startswith("/"))
|
||||
url = url.substring(1)
|
||||
|
||||
// is it still a path with at least a one char folder ?
|
||||
if (cachefile.indexOf('/')>0) {
|
||||
var path = cachefile.split('/')
|
||||
|
||||
// last elem is the filename
|
||||
while (path.length>1) {
|
||||
var current_folder = path.shift()
|
||||
try {
|
||||
FS.createFolder(dirpath, current_folder, true, true)
|
||||
//FS.createPath('/', dirname, true, true)
|
||||
} catch (err) {
|
||||
if (err.code !== 'EEXIST') throw err
|
||||
}
|
||||
dirpath = dirpath + "/" + current_folder
|
||||
}
|
||||
console.log("+dir: "+dirpath+" +file: " + path.shift())
|
||||
} else {
|
||||
// this is a root folder, abort
|
||||
if (url.indexOf(".") <1 )
|
||||
return -1
|
||||
}
|
||||
cachefile = "/" + url
|
||||
console.log("in / +" + cachefile)
|
||||
}
|
||||
|
||||
try {
|
||||
if (url[0]==":")
|
||||
url = url.substr(1)
|
||||
else {
|
||||
// [TODO:do some tests there for your CORS integration]
|
||||
if (window.urls.cors)
|
||||
url = window.urls.cors(url)
|
||||
}
|
||||
|
||||
var ab = awfull_get(url)
|
||||
|
||||
// is file found and complete ?
|
||||
if (window.currentTransferSize<0)
|
||||
return -1
|
||||
var ret = ab.length
|
||||
|
||||
window.urls.id += 1
|
||||
if (!cachefile){
|
||||
cachefile = "cache_"+window.urls.id
|
||||
ret = window.urls.id
|
||||
}
|
||||
FS.createDataFile("/", cachefile, ab, true, true);
|
||||
return ret
|
||||
} catch (x) {
|
||||
console.log("wasm_file_open :"+x)
|
||||
return -1
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
function wasm_file_exists(url, need_dot) {
|
||||
// need_dot reminds we can't check for directory on webserver
|
||||
// but we can check for a know file (probaby with a dot) under it
|
||||
// -1 not found , 1 is a file on server , 2 is a directory
|
||||
|
||||
function url_exists(url,code) {
|
||||
var xhr = new XMLHttpRequest()
|
||||
xhr.open('HEAD', url, false)
|
||||
xhr.send()
|
||||
if (xhr.status == 200 )
|
||||
return code
|
||||
return -1
|
||||
}
|
||||
|
||||
// we know those are all MEMFS local files.
|
||||
// and yes it's the same folder name as in another OS apps
|
||||
if (url.startswith('assets/'))
|
||||
return -1
|
||||
|
||||
if (url.endswith('.mpy'))
|
||||
return -1
|
||||
|
||||
|
||||
// are we possibly doing folder checking ?
|
||||
if (need_dot) {
|
||||
|
||||
|
||||
// .mpy is blacklisted for now
|
||||
// so if it's not .py then it's a folder check.
|
||||
if (!url.endswith('.py')) {
|
||||
var found = -1
|
||||
|
||||
// TODO: gain 1 call if .py exists we can discard both __init__ and index checks
|
||||
// -> would need a path cache that is usefull anyway
|
||||
|
||||
// package search
|
||||
found = url_exists( url + '/__init__.py' , 2 )
|
||||
//console.log("wasm_([dir]/file)_exists ? :"+url+ ' --> ' + '/__init__.py => '+found)
|
||||
if (found>0) return found
|
||||
|
||||
//namespace search
|
||||
found = url_exists( url + window.urls.index , 2 )
|
||||
//console.log("wasm_([dir]/file)_exists ? :"+url+ ' --> ' + window.urls.index + " => "+found)
|
||||
if (found>0) return found
|
||||
}
|
||||
|
||||
// if name has no dot then it was a folder check
|
||||
//console.log("wasm_(dir/[file])_exists ? :"+url)
|
||||
need_dot = url.split('.').pop()
|
||||
if (need_dot==url) {
|
||||
console.log("wasm_file_exists not-a-file :"+url)
|
||||
return -1
|
||||
}
|
||||
}
|
||||
|
||||
// default is a file search
|
||||
return url_exists(url, 1)
|
||||
}
|
||||
|
||||
|
||||
@ -1,37 +0,0 @@
|
||||
Micropython on wasm platform
|
||||
----------------------------
|
||||
|
||||
Some Python file operations are synchronous and won't fit in javascript async I/O system
|
||||
without performance sacrifice ( using EMTERPRETER ) or changing python code ( using asyncio file operation ).
|
||||
|
||||
some of them include :
|
||||
|
||||
os.path.exists()
|
||||
open()
|
||||
file.read()
|
||||
os.stat()
|
||||
os.path.getsize()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
It's still possible - if files are reasonably small and fast to access - to add synchronous operations to micropython
|
||||
via a cache system to add script compatibility .
|
||||
given some restrictions.
|
||||
|
||||
os.path.exists() will hammer http server via HEAD instead of GET, so results should be cached. Polling should not be used.
|
||||
|
||||
open() a file means downloading it entirely in a blocking manner.
|
||||
open() must be the first operation called.
|
||||
|
||||
|
||||
any other file operation will then success.
|
||||
|
||||
|
||||
|
||||
You will need to provide two functions in your js loader.
|
||||
These are provided as examples and only cover some usefull cases.
|
||||
|
||||
see docs/wasm_file_api.js for a dumb implementation using MEMFS as a cache.
|
||||
|
||||
@ -1 +0,0 @@
|
||||
/* This exists to keep 'emcc' from thinking we are trying to precompile headers. */
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.4 KiB |
@ -1,40 +0,0 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013, 2014 Damien P. George
|
||||
* Copyright (c) 2016 Paul Sokolovsky
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef MICROPY_INCLUDED_UNIX_FDFILE_H
|
||||
#define MICROPY_INCLUDED_UNIX_FDFILE_H
|
||||
|
||||
#include "py/obj.h"
|
||||
|
||||
typedef struct _mp_obj_fdfile_t {
|
||||
mp_obj_base_t base;
|
||||
int fd;
|
||||
} mp_obj_fdfile_t;
|
||||
|
||||
extern const mp_obj_type_t mp_type_fileio;
|
||||
extern const mp_obj_type_t mp_type_textio;
|
||||
|
||||
#endif // MICROPY_INCLUDED_UNIX_FDFILE_H
|
||||
@ -1,315 +0,0 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013, 2014 Damien P. George
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "py/runtime.h"
|
||||
#include "py/stream.h"
|
||||
#include "py/builtin.h"
|
||||
#include "py/mphal.h"
|
||||
#include "fdfile.h"
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include "emscripten.h"
|
||||
#else
|
||||
#define EMSCRIPTEN_KEEPALIVE
|
||||
#endif
|
||||
|
||||
#if MICROPY_PY_IO && !MICROPY_VFS
|
||||
|
||||
#ifdef MICROPY_CPYTHON_COMPAT
|
||||
STATIC void check_fd_is_open(const mp_obj_fdfile_t *o) {
|
||||
if (o->fd < 0) {
|
||||
mp_raise_ValueError("I/O operation on closed file");
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define check_fd_is_open(o)
|
||||
#endif
|
||||
|
||||
//included from fdfile
|
||||
//extern const mp_obj_type_t mp_type_fileio;
|
||||
//extern const mp_obj_type_t mp_type_textio;
|
||||
|
||||
STATIC void fdfile_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
(void)kind;
|
||||
mp_obj_fdfile_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
mp_printf(print, "<io.%s %d>", mp_obj_get_type_str(self_in), self->fd);
|
||||
}
|
||||
|
||||
STATIC mp_uint_t fdfile_read(mp_obj_t o_in, void *buf, mp_uint_t size, int *errcode) {
|
||||
mp_obj_fdfile_t *o = MP_OBJ_TO_PTR(o_in);
|
||||
check_fd_is_open(o);
|
||||
mp_int_t r = read(o->fd, buf, size);
|
||||
if (r == -1) {
|
||||
*errcode = errno;
|
||||
return MP_STREAM_ERROR;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
STATIC mp_uint_t fdfile_write(mp_obj_t o_in, const void *buf, mp_uint_t size, int *errcode) {
|
||||
mp_obj_fdfile_t *o = MP_OBJ_TO_PTR(o_in);
|
||||
check_fd_is_open(o);
|
||||
#if MICROPY_PY_OS_DUPTERM
|
||||
if (o->fd <= STDERR_FILENO) {
|
||||
mp_hal_stdout_tx_strn(buf, size);
|
||||
return size;
|
||||
}
|
||||
#endif
|
||||
mp_int_t r = write(o->fd, buf, size);
|
||||
while (r == -1 && errno == EINTR) {
|
||||
if (MP_STATE_VM(mp_pending_exception) != MP_OBJ_NULL) {
|
||||
mp_obj_t obj = MP_STATE_VM(mp_pending_exception);
|
||||
MP_STATE_VM(mp_pending_exception) = MP_OBJ_NULL;
|
||||
nlr_raise(obj);
|
||||
}
|
||||
r = write(o->fd, buf, size);
|
||||
}
|
||||
if (r == -1) {
|
||||
*errcode = errno;
|
||||
return MP_STREAM_ERROR;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
STATIC mp_uint_t fdfile_ioctl(mp_obj_t o_in, mp_uint_t request, uintptr_t arg, int *errcode) {
|
||||
mp_obj_fdfile_t *o = MP_OBJ_TO_PTR(o_in);
|
||||
check_fd_is_open(o);
|
||||
switch (request) {
|
||||
case MP_STREAM_SEEK: {
|
||||
struct mp_stream_seek_t *s = (struct mp_stream_seek_t*)arg;
|
||||
off_t off = lseek(o->fd, s->offset, s->whence);
|
||||
if (off == (off_t)-1) {
|
||||
*errcode = errno;
|
||||
return MP_STREAM_ERROR;
|
||||
}
|
||||
s->offset = off;
|
||||
return 0;
|
||||
}
|
||||
case MP_STREAM_FLUSH:
|
||||
if (fsync(o->fd) < 0) {
|
||||
*errcode = errno;
|
||||
return MP_STREAM_ERROR;
|
||||
}
|
||||
return 0;
|
||||
case MP_STREAM_CLOSE:
|
||||
close(o->fd);
|
||||
#ifdef MICROPY_CPYTHON_COMPAT
|
||||
o->fd = -1;
|
||||
#endif
|
||||
return 0;
|
||||
case MP_STREAM_GET_FILENO:
|
||||
return o->fd;
|
||||
default:
|
||||
*errcode = EINVAL;
|
||||
return MP_STREAM_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
STATIC mp_obj_t fdfile___exit__(size_t n_args, const mp_obj_t *args) {
|
||||
(void)n_args;
|
||||
return mp_stream_close(args[0]);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(fdfile___exit___obj, 4, 4, fdfile___exit__);
|
||||
|
||||
STATIC mp_obj_t fdfile_fileno(mp_obj_t self_in) {
|
||||
mp_obj_fdfile_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
check_fd_is_open(self);
|
||||
return MP_OBJ_NEW_SMALL_INT(self->fd);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(fdfile_fileno_obj, fdfile_fileno);
|
||||
|
||||
// Note: encoding is ignored for now; it's also not a valid kwarg for CPython's FileIO,
|
||||
// but by adding it here we can use one single mp_arg_t array for open() and FileIO's constructor
|
||||
STATIC const mp_arg_t file_open_args[] = {
|
||||
{ MP_QSTR_file, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_rom_obj = MP_ROM_PTR(&mp_const_none_obj)} },
|
||||
{ MP_QSTR_mode, MP_ARG_OBJ, {.u_obj = MP_OBJ_NEW_QSTR(MP_QSTR_r)} },
|
||||
{ MP_QSTR_buffering, MP_ARG_OBJ, {.u_rom_obj = MP_ROM_PTR(&mp_const_none_obj)} },
|
||||
{ MP_QSTR_encoding, MP_ARG_OBJ, {.u_rom_obj = MP_ROM_PTR(&mp_const_none_obj)} },
|
||||
};
|
||||
|
||||
|
||||
#define FILE_OPEN_NUM_ARGS MP_ARRAY_SIZE(file_open_args)
|
||||
|
||||
// FIXME:
|
||||
extern int wasm_file_open(const char *url);
|
||||
|
||||
STATIC mp_obj_t fdfile_open(const mp_obj_type_t *type, mp_arg_val_t *args) {
|
||||
mp_obj_fdfile_t *o = m_new_obj(mp_obj_fdfile_t);
|
||||
const char *mode_s = mp_obj_str_get_str(args[1].u_obj);
|
||||
int can_online = 0;
|
||||
int mode_rw = 0, mode_x = 0;
|
||||
while (*mode_s) {
|
||||
switch (*mode_s++) {
|
||||
case 'r':
|
||||
can_online = 1;
|
||||
mode_rw = O_RDONLY;
|
||||
break;
|
||||
case 'w':
|
||||
mode_rw = O_WRONLY;
|
||||
mode_x = O_CREAT | O_TRUNC;
|
||||
break;
|
||||
case 'a':
|
||||
mode_rw = O_WRONLY;
|
||||
mode_x = O_CREAT | O_APPEND;
|
||||
break;
|
||||
case '+':
|
||||
mode_rw = O_RDWR;
|
||||
break;
|
||||
#if MICROPY_PY_IO_FILEIO
|
||||
// If we don't have io.FileIO, then files are in text mode implicitly
|
||||
case 'b':
|
||||
type = &mp_type_fileio;
|
||||
break;
|
||||
case 't':
|
||||
type = &mp_type_textio;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
o->base.type = type;
|
||||
|
||||
mp_obj_t fid = args[0].u_obj;
|
||||
|
||||
if (MP_OBJ_IS_SMALL_INT(fid)) {
|
||||
o->fd = MP_OBJ_SMALL_INT_VALUE(fid);
|
||||
return MP_OBJ_FROM_PTR(o);
|
||||
}
|
||||
|
||||
const char *fname = mp_obj_str_get_str(fid);
|
||||
int fd=0;
|
||||
|
||||
if (can_online)
|
||||
fd = wasm_file_open( fname );
|
||||
|
||||
if (!fd)
|
||||
fd = open(fname, mode_x | mode_rw, 0644);
|
||||
|
||||
if (fd == -1) {
|
||||
mp_raise_OSError(errno);
|
||||
}
|
||||
o->fd = fd;
|
||||
return MP_OBJ_FROM_PTR(o);
|
||||
}
|
||||
|
||||
STATIC mp_obj_t
|
||||
fdfile_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
|
||||
mp_arg_val_t arg_vals[FILE_OPEN_NUM_ARGS];
|
||||
mp_arg_parse_all_kw_array(n_args, n_kw, args, FILE_OPEN_NUM_ARGS, file_open_args, arg_vals);
|
||||
return fdfile_open(type, arg_vals);
|
||||
}
|
||||
|
||||
STATIC const mp_rom_map_elem_t
|
||||
rawfile_locals_dict_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR_fileno), MP_ROM_PTR(&fdfile_fileno_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_readlines), MP_ROM_PTR(&mp_stream_unbuffered_readlines_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_seek), MP_ROM_PTR(&mp_stream_seek_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_tell), MP_ROM_PTR(&mp_stream_tell_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_flush), MP_ROM_PTR(&mp_stream_flush_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&mp_stream_close_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&mp_identity_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&fdfile___exit___obj) },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(rawfile_locals_dict, rawfile_locals_dict_table);
|
||||
|
||||
#if MICROPY_PY_IO_FILEIO
|
||||
STATIC const mp_stream_p_t
|
||||
fileio_stream_p = {
|
||||
.read = fdfile_read,
|
||||
.write = fdfile_write,
|
||||
.ioctl = fdfile_ioctl,
|
||||
};
|
||||
|
||||
const mp_obj_type_t
|
||||
mp_type_fileio = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_FileIO,
|
||||
.print = fdfile_print,
|
||||
.make_new = fdfile_make_new,
|
||||
.getiter = mp_identity_getiter,
|
||||
.iternext = mp_stream_unbuffered_iter,
|
||||
.protocol = &fileio_stream_p,
|
||||
.locals_dict = (mp_obj_dict_t*)&rawfile_locals_dict,
|
||||
};
|
||||
#endif
|
||||
|
||||
STATIC const mp_stream_p_t
|
||||
textio_stream_p = {
|
||||
.read = fdfile_read,
|
||||
.write = fdfile_write,
|
||||
.ioctl = fdfile_ioctl,
|
||||
.is_text = true,
|
||||
};
|
||||
|
||||
const mp_obj_type_t
|
||||
mp_type_textio = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_TextIOWrapper,
|
||||
.print = fdfile_print,
|
||||
.make_new = fdfile_make_new,
|
||||
.getiter = mp_identity_getiter,
|
||||
.iternext = mp_stream_unbuffered_iter,
|
||||
.protocol = &textio_stream_p,
|
||||
.locals_dict = (mp_obj_dict_t*)&rawfile_locals_dict,
|
||||
};
|
||||
|
||||
// Factory function for I/O stream classes
|
||||
mp_obj_t
|
||||
mp_builtin_open(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) {
|
||||
// TODO: analyze buffering args and instantiate appropriate type
|
||||
mp_arg_val_t arg_vals[FILE_OPEN_NUM_ARGS];
|
||||
mp_arg_parse_all(n_args, args, kwargs, FILE_OPEN_NUM_ARGS, file_open_args, arg_vals);
|
||||
return fdfile_open(&mp_type_textio, arg_vals);
|
||||
}
|
||||
|
||||
MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_open_obj, 1, mp_builtin_open);
|
||||
|
||||
/*
|
||||
EMSCRIPTEN_KEEPALIVE mp_obj_t
|
||||
mp_builtin_open_obj(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) {
|
||||
// TODO: analyze buffering args and instantiate appropriate type
|
||||
#pragma message "finally there"
|
||||
mp_arg_val_t arg_vals[FILE_OPEN_NUM_ARGS];
|
||||
mp_arg_parse_all(n_args, args, kwargs, FILE_OPEN_NUM_ARGS, file_open_args, arg_vals);
|
||||
return fdfile_open(&mp_type_textio, arg_vals);
|
||||
}
|
||||
*/
|
||||
const mp_obj_fdfile_t mp_sys_stdin_obj = { .base = {&mp_type_textio}, .fd = STDIN_FILENO };
|
||||
const mp_obj_fdfile_t mp_sys_stdout_obj = { .base = {&mp_type_textio}, .fd = STDOUT_FILENO };
|
||||
const mp_obj_fdfile_t mp_sys_stderr_obj = { .base = {&mp_type_textio}, .fd = STDERR_FILENO };
|
||||
#endif // MICROPY_PY_IO && !MICROPY_VFS
|
||||
@ -33,7 +33,7 @@ mergeInto(LibraryManager.library, {
|
||||
process.stdout.write(b);
|
||||
} else {
|
||||
var c = String.fromCharCode(getValue(ptr + i, 'i8'));
|
||||
var mp_js_stdout = window.top.document.getElementById('mp_js_stdout');
|
||||
var mp_js_stdout = document.getElementById('mp_js_stdout');
|
||||
var print = new Event('print');
|
||||
print.data = c;
|
||||
mp_js_stdout.dispatchEvent(print);
|
||||
|
||||
@ -1,146 +0,0 @@
|
||||
<!doctype html>
|
||||
<!-- Updated for 6.0 -->
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
body {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
<title>hidden iframe</title>
|
||||
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/BrowserFS/2.0.0/browserfs.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/lz-string/1.4.4/lz-string.js" type="text/javascript" charset="utf-8"></script>
|
||||
</head>
|
||||
<body>
|
||||
<!-- scripts -->
|
||||
<script src="docs/wasm_file_api.js"></script>
|
||||
<script src="lvgl_mp.js"></script>
|
||||
<script>
|
||||
var mp_js_stdout;
|
||||
/*Write text to the terminal */
|
||||
function sendText(text) {
|
||||
var print = new Event('print');
|
||||
print.data = text;
|
||||
if(mp_js_stdout === null) {
|
||||
console.log("Stdout is null???");
|
||||
}
|
||||
mp_js_stdout.dispatchEvent(print);
|
||||
}
|
||||
function reloadScript(target_script) {
|
||||
var url = [location.protocol, '//', location.host, location.pathname].join('');
|
||||
window.location.replace(url + "?env=dev&script=" + target_script);
|
||||
}
|
||||
function processScriptArg(url){
|
||||
// read text from URL location
|
||||
var request = new XMLHttpRequest();
|
||||
console.log("GET " + url);
|
||||
request.open('GET', url, true);
|
||||
request.send(null);
|
||||
request.onreadystatechange = function () {
|
||||
if (request.readyState === 4 && request.status === 200) {
|
||||
var type = request.getResponseHeader('Content-Type');
|
||||
if (type.indexOf("text") !== 1) {
|
||||
console.log(request.reponseText);
|
||||
if(request.responseText === undefined)
|
||||
return;
|
||||
mp_js_do_str(request.responseText);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
function decompressScript(compressed) {
|
||||
var script = LZString.decompressFromEncodedURIComponent(compressed);
|
||||
mp_js_do_str(script);
|
||||
}
|
||||
|
||||
function getSearchArg(argname) {
|
||||
/* Run custom script if passed */
|
||||
var custom = undefined;
|
||||
try {
|
||||
custom = new URL(window.location.href).searchParams.get(argname);
|
||||
} catch (e) {
|
||||
console.log(e + ": URL seems to be unsupported");
|
||||
}
|
||||
return custom;
|
||||
}
|
||||
|
||||
Module.canvas = (function() {
|
||||
var canvas = window.top.document.getElementById('canvas');
|
||||
return canvas;
|
||||
})();
|
||||
var lines = [
|
||||
"import lvgl as lv",
|
||||
"lv.init()",
|
||||
"import SDL",
|
||||
"SDL.init()",
|
||||
|
||||
/* Register SDL display driver. */
|
||||
"disp_buf1 = lv.disp_buf_t()",
|
||||
"buf1_1 = bytes(480*10)",
|
||||
"lv.disp_buf_init(disp_buf1,buf1_1, None, len(buf1_1)//4)",
|
||||
"disp_drv = lv.disp_drv_t()",
|
||||
"lv.disp_drv_init(disp_drv)",
|
||||
"disp_drv.buffer = disp_buf1",
|
||||
"disp_drv.flush_cb = SDL.monitor_flush",
|
||||
"disp_drv.hor_res = 480",
|
||||
"disp_drv.ver_res = 320",
|
||||
"lv.disp_drv_register(disp_drv)",
|
||||
/*Regsiter SDL mouse driver*/
|
||||
"indev_drv = lv.indev_drv_t()",
|
||||
"lv.indev_drv_init(indev_drv)",
|
||||
"indev_drv.type = lv.INDEV_TYPE.POINTER;",
|
||||
"indev_drv.read_cb = SDL.mouse_read;",
|
||||
"lv.indev_drv_register(indev_drv);",
|
||||
/* Create a screen with a button and a label */
|
||||
"scr = lv.obj()",
|
||||
"btn = lv.btn(scr)",
|
||||
"btn.align(lv.scr_act(), lv.ALIGN.CENTER, 0, 0)",
|
||||
"label = lv.label(btn)",
|
||||
"label.set_text('Button')",
|
||||
/* Load the screen */
|
||||
"lv.scr_load(scr)"
|
||||
];
|
||||
|
||||
/*Initialization function*/
|
||||
function startRunning() {
|
||||
/*Setup printing event handler*/
|
||||
|
||||
mp_js_stdout = window.parent.document.getElementById("mp_js_stdout");
|
||||
if(mp_js_stdout === undefined || mp_js_stdout === null) {
|
||||
throw "Could not retrieve parent element";
|
||||
}
|
||||
/*Initialize MicroPython itself*/
|
||||
mp_js_init(1 * 1024 * 1024);
|
||||
|
||||
var compressedScript = window.parent.document.getElementById("emscripten-iframe").getAttribute("data-cscript");
|
||||
if(compressedScript !== undefined && compressedScript !== null)
|
||||
decompressScript(compressedScript);
|
||||
|
||||
/*Setup lv_task_handler loop*/
|
||||
var the_mp_handle_pending = Module.cwrap('mp_handle_pending', null);
|
||||
function handle_pending() {
|
||||
the_mp_handle_pending();
|
||||
setTimeout(handle_pending, 10);
|
||||
}
|
||||
/*Initialize the REPL.*/
|
||||
mp_js_init_repl();
|
||||
/*Start the main loop, asynchronously.*/
|
||||
handle_pending();
|
||||
window.top.reenableButton();
|
||||
}
|
||||
window.onload = function() {
|
||||
console.log("onload");
|
||||
|
||||
startRunning();
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@ -1,402 +0,0 @@
|
||||
<!doctype html>
|
||||
<!-- Updated for 6.0 -->
|
||||
<html>
|
||||
<head>
|
||||
|
||||
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:300,400,600">
|
||||
<link rel="stylesheet" href="https://littlevgl.com/bootstrap/css/bootstrap.min.css"/>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/xterm/3.14.4/xterm.min.css" />
|
||||
<link rel="stylesheet" href="https://littlevgl.com/common.css"/>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.9.0/css/all.min.css"/>
|
||||
<title>LittlevGL/MicroPython Simulator</title>
|
||||
<style>
|
||||
* {
|
||||
font-size: normal;
|
||||
}
|
||||
html, body {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
min-width: 100%;
|
||||
min-height: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
#mp_js_stdout {
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
}
|
||||
#editor {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
}
|
||||
iframe {
|
||||
width: 0;
|
||||
height: 0;
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
border: none;
|
||||
}
|
||||
#canvas {
|
||||
border: 4px black solid;
|
||||
box-sizing: content-box;
|
||||
vertical-align: top;
|
||||
display: inline-block;
|
||||
flex: none;
|
||||
width: 480px;
|
||||
height: 320px;
|
||||
min-width: 0;
|
||||
};
|
||||
a { white-space: nowrap; }
|
||||
.flex-container {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
flex-direction: column;
|
||||
}
|
||||
.flex-container> div {
|
||||
flex: none;
|
||||
}
|
||||
#editor {
|
||||
flex: auto;
|
||||
}
|
||||
.display-objects {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
#mp_js_stdout_wrapper {
|
||||
flex: 1 1 auto;
|
||||
position: relative;
|
||||
height: 328px;
|
||||
background-color: black;
|
||||
}
|
||||
#mp_js_stdout {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.ace_editor * {
|
||||
font-size: 12px;
|
||||
line-height: normal;
|
||||
}
|
||||
a.disabled {
|
||||
/* Make the disabled links grayish*/
|
||||
color: gray;
|
||||
}
|
||||
a.disabled:hover {
|
||||
text-decoration: none;
|
||||
color: gray;
|
||||
pointer-events: none;
|
||||
}
|
||||
</style>
|
||||
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
|
||||
<script src="https://littlevgl.com/bootstrap/js/bootstrap.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.4/ace.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.4/mode-python.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/xterm/3.14.5/xterm.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/xterm/3.14.5/addons/fit/fit.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/lz-string/1.4.4/lz-string.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="query.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="flex-container">
|
||||
<div style="display: inline-block; padding: 10px;" class="no-iframe">
|
||||
<h1>LittlevGL+MicroPython simulator</h1>
|
||||
<p></p>
|
||||
This is the JavaScript version of MicroPython, plus the LittlevGL bindings available at
|
||||
<a href="https://github.com/littlevgl/lv_binding_micropython">https://github.com/littlevgl/lv_binding_micropython</a>.
|
||||
<br>
|
||||
You can type your own Python code into the prompt in the usual way, or by using the editor. When you want to run your
|
||||
customized script, click Restart.
|
||||
<br>
|
||||
For examples, see the README for the MicroPython binding.
|
||||
|
||||
<p></p>
|
||||
<input type="button" disabled="disabled" id="run-button" value="Restart" onclick="runScript();"/>
|
||||
|
||||
<span>
|
||||
<a id="share-link" data-toggle="tooltip" title="Right click to share" href="">Share current script</a>
|
||||
</span>
|
||||
<input type="url" data-toggle="tooltip" title="Paste a link to a script here" placeholder="Link to online script" id="online-script" oninput="new_external_link(this.value);"/>
|
||||
|
||||
</div>
|
||||
<div id="editor">print("Hello world")</div>
|
||||
<div class="display-objects">
|
||||
|
||||
<canvas id="canvas" data-toggle="tooltip" title="This is the virtual LittlevGL screen" width="480" height="320" oncontextmenu="event.preventDefault()" tabindex="-1"></canvas>
|
||||
<div id="mp_js_stdout_wrapper">
|
||||
<div id="mp_js_stdout"></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<iframe src="about:blank" id="emscripten-iframe"></iframe>
|
||||
|
||||
<script>
|
||||
var external_link = null;
|
||||
var external_script_value = null;
|
||||
var editor, iframe, online_script_input;
|
||||
var script_passed = false;
|
||||
function new_external_link(url) {
|
||||
if(url.length > 0) {
|
||||
processScriptArg(url, false);
|
||||
}
|
||||
}
|
||||
// Ctrl+L is mandatory ! need xterm.js 3.14+
|
||||
function xterm_helper(term, key) {
|
||||
function ESC(data) {
|
||||
return String.fromCharCode(27)+data
|
||||
}
|
||||
if ( key.charCodeAt(0)==12 ) {
|
||||
var cy = 0+term.buffer.cursorY
|
||||
if ( cy > 0) {
|
||||
if (cy <= term.rows) {
|
||||
term.write( ESC("[B") )
|
||||
term.write( ESC("[J") )
|
||||
term.write( ESC("[A") )
|
||||
}
|
||||
|
||||
term.write( ESC("[A") )
|
||||
term.write( ESC("[K") )
|
||||
term.write( ESC("[1J"))
|
||||
|
||||
for (var i=1;i<cy;i++) {
|
||||
term.write( ESC("[A") )
|
||||
term.write( ESC("[M") )
|
||||
}
|
||||
term.write( ESC("[M") )
|
||||
}
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
function forward_event(event) {
|
||||
if(iframe !== undefined && iframe !== null) {
|
||||
if(iframe.contentWindow !== null)
|
||||
iframe.contentWindow.document.dispatchEvent(new MouseEvent('mouseup'));
|
||||
}
|
||||
}
|
||||
/* From https://stackoverflow.com/a/1634841 */
|
||||
function removeURLParameter(url, parameter) {
|
||||
//prefer to use l.search if you have a location/link object
|
||||
var urlparts = url.split('?');
|
||||
if (urlparts.length >= 2) {
|
||||
|
||||
var prefix = encodeURIComponent(parameter) + '=';
|
||||
var pars = urlparts[1].split(/[&;]/g);
|
||||
|
||||
//reverse iteration as may be destructive
|
||||
for (var i = pars.length; i-- > 0;) {
|
||||
//idiom for string.startsWith
|
||||
if (pars[i].lastIndexOf(prefix, 0) !== -1) {
|
||||
pars.splice(i, 1);
|
||||
}
|
||||
}
|
||||
|
||||
return urlparts[0] + (pars.length > 0 ? '?' + pars.join('&') : '');
|
||||
}
|
||||
return url;
|
||||
}
|
||||
document.onmouseup = forward_event;
|
||||
function editor_change() {
|
||||
var new_href;
|
||||
$("#share-link").removeClass("disabled");
|
||||
if(editor.getValue() != external_script_value) {
|
||||
online_script_input.value = "";
|
||||
var script_string = LZString.compressToEncodedURIComponent(editor.getValue());
|
||||
$("#script-compressed").val(script_string);
|
||||
new_href = update_query_string(window.location.href, "script_direct", script_string);
|
||||
new_href = removeURLParameter(new_href, "script");
|
||||
|
||||
if(new_href.length > 2000) {
|
||||
$("#share-link").text("URL is too long to be shared");
|
||||
new_href = "#";
|
||||
$("#share-link").addClass("disabled");
|
||||
} else
|
||||
$("#share-link").text("Share custom script");
|
||||
} else {
|
||||
online_script_input.value = external_link;
|
||||
new_href = update_query_string(window.location.href, "script", external_link);
|
||||
new_href = removeURLParameter(new_href, "script_direct");
|
||||
$("#share-link").text("Share linked script");
|
||||
}
|
||||
// Create a dummy element to parse the URI with
|
||||
$("#share-link").attr("href", new_href);
|
||||
}
|
||||
function runScript() {
|
||||
var $this = $("#run-button");
|
||||
$this.prop("disabled", "disabled");
|
||||
term.write('\x1bc');
|
||||
|
||||
|
||||
const context = document.getElementById("canvas").getContext('2d');
|
||||
|
||||
context.clearRect(0, 0, canvas.width, canvas.height);
|
||||
|
||||
|
||||
|
||||
iframe.setAttribute("data-cscript", LZString.compressToEncodedURIComponent(editor.getValue()));
|
||||
|
||||
clear_iframe(iframe);
|
||||
iframe.src = get_iframe_url() + "×tamp=" + new Date().getTime();
|
||||
iframe.contentWindow.location.href = iframe.src;
|
||||
console.log("Iframe src: " + iframe.src);
|
||||
}
|
||||
function reenableButton() {
|
||||
$("#run-button").removeProp('disabled');
|
||||
}
|
||||
function get_iframe_url() {
|
||||
/* Assemble the URL */
|
||||
var num_url_chars = (window.location.href.indexOf('?'));
|
||||
var base_url = window.location.href.substr(0, (num_url_chars == -1) ? undefined : num_url_chars);
|
||||
var newPathname = base_url.substr(0, base_url.lastIndexOf('/'));
|
||||
newPathname += "/lvgl.html" + '?' + "env=dev";
|
||||
return newPathname;
|
||||
}
|
||||
function processScriptArg(url, lzstring){
|
||||
var script_passed_handler = function() {
|
||||
console.log("Script passed: " + script_passed);
|
||||
runScript();
|
||||
script_passed = false;
|
||||
};
|
||||
if(!lzstring) {
|
||||
var prev_external_link = external_link;
|
||||
var request = null;
|
||||
|
||||
var error_handler = function() {
|
||||
if(prev_external_link != null) {
|
||||
external_link = prev_external_link;
|
||||
online_script_input.value = external_link;
|
||||
}
|
||||
if(request != null)
|
||||
alert("Failed to load script due to error " + request.status + ": " + request.statusText + "\nThe contents of the external link box have been reverted.");
|
||||
else
|
||||
alert("The URL you passed is invalid.");
|
||||
};
|
||||
|
||||
try {
|
||||
new URL(url);
|
||||
} catch(e) {
|
||||
error_handler();
|
||||
return;
|
||||
}
|
||||
|
||||
external_link = url;
|
||||
if(online_script_input.value != external_link)
|
||||
online_script_input.value = external_link;
|
||||
// read text from URL location
|
||||
request = new XMLHttpRequest();
|
||||
console.log("GET " + url);
|
||||
request.overrideMimeType("text/plain");
|
||||
request.open('GET', url, true);
|
||||
request.send(null);
|
||||
request.onerror = error_handler;
|
||||
request.onreadystatechange = function () {
|
||||
if (request.readyState === 4) {
|
||||
if(request.status == 200) {
|
||||
console.log(request.reponseText);
|
||||
if(request.responseText === undefined)
|
||||
return;
|
||||
editor.session.getUndoManager().reset();
|
||||
external_script_value = request.responseText;
|
||||
editor.session.setValue(request.responseText, -1);
|
||||
script_passed_handler();
|
||||
} else {
|
||||
error_handler();
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
external_link = null;
|
||||
// decompress LZString
|
||||
editor.session.setValue(LZString.decompressFromEncodedURIComponent(url));
|
||||
script_passed_handler();
|
||||
}
|
||||
|
||||
}
|
||||
function getSearchArg(argname) {
|
||||
/* Run custom script if passed */
|
||||
var custom = undefined;
|
||||
try {
|
||||
custom = new URL(window.location.href).searchParams.get(argname);
|
||||
} catch (e) {
|
||||
console.log(e + ": URL seems to be unsupported");
|
||||
}
|
||||
return custom;
|
||||
}
|
||||
function clear_iframe(iframe) {
|
||||
iframe.contentWindow.document.open();
|
||||
iframe.contentWindow.document.write("");
|
||||
iframe.contentWindow.document.close();
|
||||
}
|
||||
$(window).load(function() {
|
||||
$(document).on('shown.bs.tooltip', function (e) {
|
||||
setTimeout(function () {
|
||||
$(e.target).tooltip('hide');
|
||||
}, 5000);
|
||||
});
|
||||
/* Enable tooltips */
|
||||
$('[data-toggle="tooltip"]').tooltip();
|
||||
|
||||
editor = ace.edit("editor");
|
||||
editor.getSession().setUseWrapMode(true);
|
||||
editor.setAutoScrollEditorIntoView(true);
|
||||
var PythonMode = ace.require("ace/mode/python").Mode;
|
||||
editor.session.setMode(new PythonMode());
|
||||
iframe = document.getElementById("emscripten-iframe");
|
||||
online_script_input = document.getElementById("online-script");
|
||||
iframe.src = "about:blank";
|
||||
iframe.contentWindow.location.href = iframe.src;
|
||||
clear_iframe(iframe);
|
||||
|
||||
|
||||
|
||||
Terminal.applyAddon(fit);
|
||||
term = new Terminal({
|
||||
tabStopWidth : 8,
|
||||
cursorBlink : true,
|
||||
cursorStyle : 'block',
|
||||
applicationCursor : true
|
||||
});
|
||||
mp_js_stdout = document.getElementById('mp_js_stdout');
|
||||
mp_js_stdout.value = "";
|
||||
term.open(mp_js_stdout);
|
||||
term.fit();
|
||||
term.on('data', function(key, e) {
|
||||
if ( xterm_helper(term, key) ) {
|
||||
for(var i = 0; i < key.length; i++) {
|
||||
if(iframe.contentWindow !== null)
|
||||
iframe.contentWindow.mp_js_process_char(key.charCodeAt(i));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
mp_js_stdout.addEventListener('print', function(e) {
|
||||
text = e.data;
|
||||
term.write(text);
|
||||
}, false);
|
||||
editor.getSession().on('change', editor_change);
|
||||
editor.resize();
|
||||
term.fit();
|
||||
var script = getSearchArg("script");
|
||||
var script_direct = getSearchArg("script_direct");
|
||||
if(script_direct !== undefined && script_direct !== null) {
|
||||
script_passed = true;
|
||||
processScriptArg(script_direct, true);
|
||||
} else if(script !== undefined && script !== null) {
|
||||
script_passed = true;
|
||||
processScriptArg(script);
|
||||
} else
|
||||
runScript();
|
||||
});
|
||||
$(window).resize(function() {
|
||||
editor.resize();
|
||||
term.fit();
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
340378
ports/javascript/lvgl_mp.js
340378
ports/javascript/lvgl_mp.js
File diff suppressed because one or more lines are too long
@ -28,8 +28,6 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include "genhdr/mpversion.h"
|
||||
|
||||
#include "py/compile.h"
|
||||
#include "py/runtime.h"
|
||||
@ -40,14 +38,9 @@
|
||||
|
||||
#include "library.h"
|
||||
|
||||
#define LEX_SRC_STR (1)
|
||||
#define LEX_SRC_VSTR (2)
|
||||
#define LEX_SRC_FILENAME (3)
|
||||
#define LEX_SRC_STDIN (4)
|
||||
|
||||
|
||||
#if MICROPY_ENABLE_COMPILER
|
||||
void do_str(const char *src, mp_parse_input_kind_t input_kind) {
|
||||
int do_str(const char *src, mp_parse_input_kind_t input_kind) {
|
||||
int ret = 0;
|
||||
nlr_buf_t nlr;
|
||||
if (nlr_push(&nlr) == 0) {
|
||||
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0);
|
||||
@ -59,138 +52,28 @@ void do_str(const char *src, mp_parse_input_kind_t input_kind) {
|
||||
} else {
|
||||
// uncaught exception
|
||||
if (mp_obj_is_subclass_fast(mp_obj_get_type((mp_obj_t)nlr.ret_val), &mp_type_SystemExit)) {
|
||||
// at the moment, the value of SystemExit is unused
|
||||
mp_obj_t exit_val = mp_obj_exception_get_value(MP_OBJ_FROM_PTR(nlr.ret_val));
|
||||
if (exit_val != mp_const_none) {
|
||||
mp_int_t int_val;
|
||||
if (mp_obj_get_int_maybe(exit_val, &int_val)) {
|
||||
ret = int_val & 255;
|
||||
} else {
|
||||
ret = 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr.ret_val);
|
||||
ret = 1;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
|
||||
#define FORCED_EXIT (0x100)
|
||||
// If exc is SystemExit, return value where FORCED_EXIT bit set,
|
||||
// and lower 8 bits are SystemExit value. For all other exceptions,
|
||||
// return 1.
|
||||
STATIC int handle_uncaught_exception(mp_obj_base_t *exc) {
|
||||
// check for SystemExit
|
||||
if (mp_obj_is_subclass_fast(MP_OBJ_FROM_PTR(exc->type), MP_OBJ_FROM_PTR(&mp_type_SystemExit))) {
|
||||
// None is an exit value of 0; an int is its value; anything else is 1
|
||||
mp_obj_t exit_val = mp_obj_exception_get_value(MP_OBJ_FROM_PTR(exc));
|
||||
mp_int_t val = 0;
|
||||
if (exit_val != mp_const_none && !mp_obj_get_int_maybe(exit_val, &val)) {
|
||||
val = 1;
|
||||
}
|
||||
return FORCED_EXIT | (val & 255);
|
||||
}
|
||||
|
||||
// Report all other exceptions
|
||||
mp_obj_print_exception(&mp_plat_print, MP_OBJ_FROM_PTR(exc));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
// Returns standard error codes: 0 for success, 1 for all other errors,
|
||||
// except if FORCED_EXIT bit is set then script raised SystemExit and the
|
||||
// value of the exit is in the lower 8 bits of the return value
|
||||
STATIC int execute_from_lexer(int source_kind, const void *source, mp_parse_input_kind_t input_kind, bool is_repl) {
|
||||
nlr_buf_t nlr;
|
||||
if (nlr_push(&nlr) == 0) {
|
||||
// create lexer based on source kind
|
||||
mp_lexer_t *lex;
|
||||
if (source_kind == LEX_SRC_STR) {
|
||||
const char *line = source;
|
||||
lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, line, strlen(line), false);
|
||||
} else if (source_kind == LEX_SRC_VSTR) {
|
||||
const vstr_t *vstr = source;
|
||||
lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, vstr->buf, vstr->len, false);
|
||||
} else if (source_kind == LEX_SRC_FILENAME) {
|
||||
lex = mp_lexer_new_from_file((const char*)source);
|
||||
} else { // LEX_SRC_STDIN
|
||||
assert(false); /* Not supported */
|
||||
return 1 | FORCED_EXIT;
|
||||
}
|
||||
|
||||
qstr source_name = lex->source_name;
|
||||
|
||||
#if MICROPY_PY___FILE__
|
||||
if (input_kind == MP_PARSE_FILE_INPUT) {
|
||||
mp_store_global(MP_QSTR___file__, MP_OBJ_NEW_QSTR(source_name));
|
||||
}
|
||||
#endif
|
||||
|
||||
mp_parse_tree_t parse_tree = mp_parse(lex, input_kind);
|
||||
|
||||
mp_obj_t module_fun = mp_compile(&parse_tree, source_name, MP_EMIT_OPT_NONE, is_repl);
|
||||
|
||||
// execute it
|
||||
mp_call_function_0(module_fun);
|
||||
// check for pending exception
|
||||
if (MP_STATE_VM(mp_pending_exception) != MP_OBJ_NULL) {
|
||||
mp_obj_t obj = MP_STATE_VM(mp_pending_exception);
|
||||
MP_STATE_VM(mp_pending_exception) = MP_OBJ_NULL;
|
||||
nlr_raise(obj);
|
||||
}
|
||||
|
||||
|
||||
nlr_pop();
|
||||
return 0;
|
||||
|
||||
} else {
|
||||
// uncaught exception
|
||||
return handle_uncaught_exception(nlr.ret_val);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
STATIC void mp_js_tx_str(const char *str)
|
||||
{
|
||||
mp_js_write(str, strlen(str));
|
||||
}
|
||||
|
||||
STATIC char *prompt(const char *str)
|
||||
{
|
||||
static char *buf[256];
|
||||
}
|
||||
|
||||
STATIC int do_repl(void) {
|
||||
mp_js_tx_str("MicroPython " MICROPY_GIT_TAG " on " MICROPY_BUILD_DATE "; "
|
||||
MICROPY_PY_SYS_PLATFORM " version\nUse Ctrl-D to exit, Ctrl-E for paste mode\n");
|
||||
|
||||
// use simple readline
|
||||
|
||||
for (;;) {
|
||||
char *line = prompt(">>> ");
|
||||
if (line == NULL) {
|
||||
// EOF
|
||||
return 0;
|
||||
}
|
||||
while (mp_repl_continue_with_input(line)) {
|
||||
char *line2 = prompt("... ");
|
||||
if (line2 == NULL) {
|
||||
break;
|
||||
}
|
||||
char *line3 = strjoin(line, '\n', line2);
|
||||
free(line);
|
||||
free(line2);
|
||||
line = line3;
|
||||
}
|
||||
|
||||
int ret = execute_from_lexer(LEX_SRC_STR, line, MP_PARSE_SINGLE_INPUT, true);
|
||||
if (ret & FORCED_EXIT) {
|
||||
return ret;
|
||||
}
|
||||
free(line);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static char *stack_top;
|
||||
|
||||
void mp_js_do_str(const char *code) {
|
||||
do_str(code, MP_PARSE_FILE_INPUT);
|
||||
int mp_js_do_str(const char *code) {
|
||||
return do_str(code, MP_PARSE_FILE_INPUT);
|
||||
}
|
||||
|
||||
int mp_js_process_char(int c) {
|
||||
@ -207,12 +90,12 @@ void mp_js_init(int heap_size) {
|
||||
#endif
|
||||
|
||||
#if MICROPY_ENABLE_PYSTACK
|
||||
static mp_obj_t pystack[128*1024];
|
||||
static mp_obj_t pystack[1024];
|
||||
mp_pystack_init(pystack, &pystack[MP_ARRAY_SIZE(pystack)]);
|
||||
#endif
|
||||
|
||||
mp_init();
|
||||
|
||||
|
||||
mp_obj_list_init(mp_sys_path, 0);
|
||||
mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR_));
|
||||
mp_obj_list_init(mp_sys_argv, 0);
|
||||
@ -242,17 +125,10 @@ mp_import_stat_t mp_import_stat(const char *path) {
|
||||
return MP_IMPORT_STAT_NO_EXIST;
|
||||
}
|
||||
|
||||
#ifndef WASM_FILE_API
|
||||
#if !MICROPY_PY_IO_FILEIO
|
||||
mp_obj_t mp_builtin_open(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) {
|
||||
return mp_const_none;
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_open_obj, 1, mp_builtin_open);
|
||||
#endif
|
||||
#else
|
||||
#pragma message "file.c will require external WASM_FILE_API functions"
|
||||
#pragma message "see docs/wasm_file_api.txt"
|
||||
#endif
|
||||
|
||||
void nlr_jump_fail(void *val) {
|
||||
while (1);
|
||||
|
||||
@ -1,2 +0,0 @@
|
||||
py/modbuiltins.c
|
||||
py/makeqstrdata.py
|
||||
@ -1,65 +0,0 @@
|
||||
import sys
|
||||
import builtins
|
||||
import types
|
||||
|
||||
# keep the builtin function accessible in this module and via imp.__import__
|
||||
__import__ = __import__
|
||||
|
||||
# Deprecated since version 3.4: Use types.ModuleType instead.
|
||||
# but micropython aims toward full 3.4
|
||||
|
||||
# Return a new empty module object called name. This object is not inserted in sys.modules.
|
||||
def new_module(name):
|
||||
return types.ModuleType(name)
|
||||
|
||||
|
||||
# not spaghetti
|
||||
def importer(name,*argv,**kw):
|
||||
global __import__
|
||||
try:
|
||||
return __import__(name,*argv)
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
file = ':{0}.py'.format(name)
|
||||
print("INFO: getting online version of",file)
|
||||
# todo open the file via open() or raise importerror
|
||||
try:
|
||||
code = open(file,'r').read()
|
||||
except:
|
||||
raise ImportError('module not found')
|
||||
|
||||
#build a empty module
|
||||
mod = types.ModuleType(name)
|
||||
|
||||
mod.__file__ = file
|
||||
|
||||
# compile module from cached file
|
||||
try:
|
||||
code = compile( code, file, 'exec')
|
||||
except Exception as e:
|
||||
sys.print_exception(e)
|
||||
raise
|
||||
|
||||
# execute it in its own empty namespace.
|
||||
try:
|
||||
ns = vars(mod)
|
||||
except:
|
||||
print("WARNING: this python implementation lacks vars()")
|
||||
ns = mod.__dict__
|
||||
|
||||
|
||||
try:
|
||||
exec( code, ns, ns)
|
||||
except Exception as e:
|
||||
sys.print_exception(e)
|
||||
raise
|
||||
|
||||
# though micropython would normally insert module before executing the whole body
|
||||
# do it after.
|
||||
sys.modules[name] = mod
|
||||
return mod
|
||||
|
||||
# install hook
|
||||
builtins.__import__ = importer
|
||||
print("__import__ is now", importer)
|
||||
@ -1 +0,0 @@
|
||||
__dict__ = globals()
|
||||
@ -1,5 +0,0 @@
|
||||
__name__ = imp.pivot_name
|
||||
__file__ = imp.pivot_file
|
||||
print('pivot',__name__,__file__, globals())
|
||||
|
||||
exec( compile( imp.pivot_code, __file__, 'exec') , globals(), globals() )
|
||||
@ -1,10 +0,0 @@
|
||||
import sys
|
||||
import builtins
|
||||
|
||||
for name in ("sys", "__main__", "builtins"):
|
||||
sys.modules[name] = __import__(name)
|
||||
|
||||
import imp
|
||||
|
||||
builtins.imp = imp
|
||||
|
||||
@ -1,24 +0,0 @@
|
||||
import sys
|
||||
import imp
|
||||
|
||||
|
||||
# not thread safe
|
||||
|
||||
def ModuleType(name):
|
||||
if sys.modules.get('name'):
|
||||
print("Error : module %s exists !"%name)
|
||||
return sys.modules[name]
|
||||
|
||||
# get a new fresh module
|
||||
# be sure to use the builtin func
|
||||
pivot = imp.__import__('imp_empty_pivot_module') #
|
||||
# low risk, who would call his module like that ?
|
||||
del sys.modules['imp_empty_pivot_module']
|
||||
|
||||
#still unknown at this time
|
||||
if hasattr(pivot,'__file__'):
|
||||
del pivot.__file__
|
||||
|
||||
pivot.__name__ = name
|
||||
|
||||
return pivot
|
||||
@ -28,53 +28,21 @@
|
||||
|
||||
// options to control how MicroPython is built
|
||||
|
||||
// options to control how Micro Python is built
|
||||
#define MICROPY_QSTR_BYTES_IN_HASH (1)
|
||||
#define MICROPY_ERROR_REPORTING (MICROPY_ERROR_REPORTING_TERSE)
|
||||
#define MICROPY_CPYTHON_COMPAT (1)
|
||||
#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_DOUBLE)
|
||||
//just in case of long urls and a local cache ?
|
||||
#define MICROPY_ALLOC_PATH_MAX (1024)
|
||||
#define MICROPY_ALLOC_PARSE_CHUNK_INIT (16)
|
||||
#define MICROPY_BUILTIN_METHOD_CHECK_SELF_ARG (0)
|
||||
#define MICROPY_CAN_OVERRIDE_BUILTINS (1)
|
||||
|
||||
#define MICROPY_MODULE_WEAK_LINKS (0)
|
||||
|
||||
#define MICROPY_MODULE_GETATTR (1)
|
||||
#define MICROPY_MODULE_SPECIAL_METHODS (1)
|
||||
|
||||
#define MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE (0)
|
||||
#define MICROPY_LONGINT_IMPL_MPZ (2)
|
||||
#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_MPZ)
|
||||
#define MPZ_DIG_SIZE (16)
|
||||
|
||||
|
||||
// You can disable the built-in MicroPython compiler by setting the following
|
||||
// config option to 0. If you do this then you won't get a REPL prompt, but you
|
||||
// will still be able to execute pre-compiled scripts, compiled with mpy-cross.
|
||||
#define MICROPY_ENABLE_COMPILER (1)
|
||||
#define MICROPY_ENABLE_EXTERNAL_IMPORT (1)
|
||||
#define MICROPY_PERSISTENT_CODE_LOAD (0)
|
||||
#define MICROPY_PERSISTENT_CODE_SAVE (0)
|
||||
|
||||
#define MICROPY_HAS_FILE_READER (1)
|
||||
#define MICROPY_READER_POSIX (0)
|
||||
#define MICROPY_HELPER_LEXER_UNIX (1)
|
||||
|
||||
#define MICROPY_PY_BUILTINS_INPUT (1)
|
||||
|
||||
|
||||
#define MICROPY_PY_COLLECTIONS_ORDEREDDICT (1)
|
||||
#define MICROPY_PY_DELATTR_SETATTR (1)
|
||||
#define MICROPY_PY_MATH_SPECIAL_FUNCTIONS (1)
|
||||
#define MICROPY_PY_MATH_FACTORIAL (1)
|
||||
|
||||
#define MICROPY_QSTR_BYTES_IN_HASH (2)
|
||||
#define MICROPY_ALLOC_PATH_MAX (256)
|
||||
#define MICROPY_ALLOC_PARSE_CHUNK_INIT (16)
|
||||
#define MICROPY_EMIT_X64 (0) //BROKEN
|
||||
#define MICROPY_EMIT_THUMB (0) //BROKEN
|
||||
#define MICROPY_EMIT_INLINE_THUMB (0)
|
||||
#define MICROPY_COMP_MODULE_CONST (1)
|
||||
#define MICROPY_COMP_MODULE_CONST (0)
|
||||
#define MICROPY_COMP_CONST (1)
|
||||
#define MICROPY_COMP_DOUBLE_TUPLE_ASSIGN (1)
|
||||
#define MICROPY_COMP_TRIPLE_TUPLE_ASSIGN (1)
|
||||
#define MICROPY_COMP_TRIPLE_TUPLE_ASSIGN (0)
|
||||
#define MICROPY_MEM_STATS (0) //BROKEN
|
||||
#define MICROPY_DEBUG_PRINTERS (0)
|
||||
#define MICROPY_ENABLE_GC (1)
|
||||
@ -82,9 +50,11 @@
|
||||
#define MICROPY_GC_USES_ALLOCATED_SIZE (1)
|
||||
#define MICROPY_REPL_EVENT_DRIVEN (1)
|
||||
#define MICROPY_HELPER_REPL (1)
|
||||
#define MICROPY_HELPER_LEXER_UNIX (0)
|
||||
#define MICROPY_ENABLE_SOURCE_LINE (1)
|
||||
#define MICROPY_ENABLE_DOC_STRING (1)
|
||||
#define MICROPY_WARNINGS (1)
|
||||
#define MICROPY_BUILTIN_METHOD_CHECK_SELF_ARG (1)
|
||||
#define MICROPY_PY_ASYNC_AWAIT (1)
|
||||
#define MICROPY_PY_BUILTINS_BYTEARRAY (1)
|
||||
#define MICROPY_PY_BUILTINS_MEMORYVIEW (1)
|
||||
@ -97,10 +67,8 @@
|
||||
#define MICROPY_PY_BUILTINS_PROPERTY (1)
|
||||
#define MICROPY_PY_BUILTINS_MIN_MAX (1)
|
||||
#define MICROPY_PY___FILE__ (1)
|
||||
#define MICROPY_PY_ALL_SPECIAL_METHODS (1)
|
||||
#define MICROPY_PY_GC (1)
|
||||
#define MICROPY_PY_ARRAY (1)
|
||||
#define MICROPY_PY_ASYNC_AWAIT (1)
|
||||
#define MICROPY_PY_ATTRTUPLE (1)
|
||||
#define MICROPY_PY_COLLECTIONS (1)
|
||||
#define MICROPY_PY_MATH (1)
|
||||
@ -138,53 +106,29 @@
|
||||
#define MICROPY_PY_SYS_PLATFORM "javascript"
|
||||
#define MICROPY_PY_UERRNO (1)
|
||||
#define MICROPY_PY_UCTYPES (1)
|
||||
#define MICROPY_PY_UCTYPES_NATIVE_C_TYPES (1)
|
||||
#define MICROPY_PY_UZLIB (1)
|
||||
#define MICROPY_PY_UJSON (1)
|
||||
#define MICROPY_PY_URE (1)
|
||||
#define MICROPY_PY_UHEAPQ (1)
|
||||
#define MICROPY_PY_LVGL (1)
|
||||
#define MICROPY_PY_UHASHLIB (1)
|
||||
#define MICROPY_PY_UBINASCII (1)
|
||||
#define MICROPY_PY_URANDOM (1)
|
||||
#define MICROPY_PY_URANDOM_EXTRA_FUNCS (1)
|
||||
#define MICROPY_PY_USELECT (0)
|
||||
#define MICROPY_PY_USELECT (1)
|
||||
#define MICROPY_PY_FRAMEBUF (1)
|
||||
#define MICROPY_STREAMS_NON_BLOCK (1)
|
||||
#define MICROPY_MODULE_WEAK_LINKS (1)
|
||||
#define MICROPY_CAN_OVERRIDE_BUILTINS (1)
|
||||
#define MICROPY_USE_INTERNAL_ERRNO (1)
|
||||
#define MICROPY_ENABLE_SCHEDULER (1)
|
||||
#define MICROPY_SCHEDULER_DEPTH (1)
|
||||
|
||||
#define MICROPY_PY_IO (1)
|
||||
#define MICROPY_PY_IO_IOBASE (1)
|
||||
#define MICROPY_PY_IO_RESOURCE_STREAM (0)
|
||||
#define MICROPY_PY_IO_FILEIO (1)
|
||||
#define MICROPY_PY_IO_BYTESIO (1)
|
||||
#define MICROPY_PY_IO_BUFFEREDWRITER (1)
|
||||
|
||||
#define MICROPY_VFS (0)
|
||||
|
||||
#define MP_SSIZE_MAX (0x7fffffff)
|
||||
|
||||
extern const struct _mp_obj_module_t mp_module_utime;
|
||||
extern const struct _mp_obj_module_t mp_module_lvgl;
|
||||
extern const struct _mp_obj_module_t mp_module_lvindev;
|
||||
extern const struct _mp_obj_module_t mp_module_SDL;
|
||||
|
||||
#if MICROPY_PY_LVGL
|
||||
#include "lib/lv_bindings/lvgl/src/lv_misc/lv_gc.h"
|
||||
#define MICROPY_PY_LVGL_DEF \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_lvgl), (mp_obj_t)&mp_module_lvgl },\
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_lvindev), (mp_obj_t)&mp_module_lvindev},\
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_SDL), (mp_obj_t)&mp_module_SDL },
|
||||
#else
|
||||
#define MICROPY_PY_LVGL_DEF
|
||||
#endif
|
||||
|
||||
#define MICROPY_PORT_BUILTIN_MODULES \
|
||||
{ MP_ROM_QSTR(MP_QSTR_utime), MP_ROM_PTR(&mp_module_utime) }, \
|
||||
MICROPY_PY_LVGL_DEF \
|
||||
|
||||
#define MICROPY_PORT_BUILTIN_MODULE_WEAK_LINKS \
|
||||
{ MP_ROM_QSTR(MP_QSTR_binascii), MP_ROM_PTR(&mp_module_ubinascii) }, \
|
||||
@ -265,10 +209,4 @@ typedef long mp_off_t;
|
||||
#define MP_STATE_PORT MP_STATE_VM
|
||||
|
||||
#define MICROPY_PORT_ROOT_POINTERS \
|
||||
LV_ROOTS \
|
||||
void *mp_lv_user_data; \
|
||||
const char *readline_hist[8];
|
||||
|
||||
|
||||
|
||||
#define MICROPY_ENABLE_EXTERNAL_IMPORT (1)
|
||||
|
||||
@ -60,11 +60,3 @@ extern int mp_interrupt_char;
|
||||
int mp_hal_get_interrupt_char(void) {
|
||||
return mp_interrupt_char;
|
||||
}
|
||||
|
||||
void mp_hal_move_cursor_back(uint pos)
|
||||
{
|
||||
mp_hal_stdout_tx_strn("\b", 1);
|
||||
}
|
||||
void mp_hal_erase_line_from_cursor(uint pos)
|
||||
{
|
||||
}
|
||||
|
||||
@ -1,70 +0,0 @@
|
||||
/**
|
||||
* Add or update a query string parameter. If no URI is given, we use the current
|
||||
* window.location.href value for the URI.
|
||||
*
|
||||
* Based on the DOM URL parser described here:
|
||||
* http://james.padolsey.com/javascript/parsing-urls-with-the-dom/
|
||||
*
|
||||
* @param (string) uri Optional: The URI to add or update a parameter in
|
||||
* @param (string) key The key to add or update
|
||||
* @param (string) value The new value to set for key
|
||||
*
|
||||
* Tested on Chrome 34, Firefox 29, IE 7 and 11
|
||||
*/
|
||||
function update_query_string( uri, key, value ) {
|
||||
|
||||
// Use window URL if no query string is provided
|
||||
if ( ! uri ) { uri = window.location.href; }
|
||||
|
||||
// Create a dummy element to parse the URI with
|
||||
var a = document.createElement( 'a' ),
|
||||
|
||||
// match the key, optional square brackets, an equals sign or end of string, the optional value
|
||||
reg_ex = new RegExp( key + '((?:\\[[^\\]]*\\])?)(=|$)(.*)' ),
|
||||
|
||||
// Setup some additional variables
|
||||
qs,
|
||||
qs_len,
|
||||
key_found = false;
|
||||
|
||||
// Use the JS API to parse the URI
|
||||
a.href = uri;
|
||||
|
||||
// If the URI doesn't have a query string, add it and return
|
||||
if ( ! a.search ) {
|
||||
|
||||
a.search = '?' + key + '=' + value;
|
||||
|
||||
return a.href;
|
||||
}
|
||||
|
||||
// Split the query string by ampersands
|
||||
qs = a.search.replace( /^\?/, '' ).split( /&(?:amp;)?/ );
|
||||
qs_len = qs.length;
|
||||
|
||||
// Loop through each query string part
|
||||
while ( qs_len > 0 ) {
|
||||
|
||||
qs_len--;
|
||||
|
||||
// Remove empty elements to prevent double ampersands
|
||||
if ( ! qs[qs_len] ) { qs.splice(qs_len, 1); continue; }
|
||||
|
||||
// Check if the current part matches our key
|
||||
if ( reg_ex.test( qs[qs_len] ) ) {
|
||||
|
||||
// Replace the current value
|
||||
qs[qs_len] = qs[qs_len].replace( reg_ex, key + '$1' ) + '=' + value;
|
||||
|
||||
key_found = true;
|
||||
}
|
||||
}
|
||||
|
||||
// If we haven't replaced any occurrences above, add the new parameter and value
|
||||
if ( ! key_found ) { qs.push( key + '=' + value ); }
|
||||
|
||||
// Set the new query string
|
||||
a.search = '?' + qs.join( '&' );
|
||||
|
||||
return a.href;
|
||||
}
|
||||
@ -1,4 +0,0 @@
|
||||
print("Hello World from an online module")
|
||||
print("__name__","=",__name__)
|
||||
print("__file__","=",__file__)
|
||||
|
||||
@ -1,33 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "py/mpconfig.h"
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include "emscripten.h"
|
||||
#endif
|
||||
|
||||
// VERY BAD
|
||||
int
|
||||
wasm_file_open(const char *url) {
|
||||
fprintf(stderr,"10:wasm_file_open[%s]\n", url);
|
||||
|
||||
if (strlen(url)>1 && url[0]==':') {
|
||||
fprintf(stderr," -> same host[%s]\n", url);
|
||||
int fidx = EM_ASM_INT({return wasm_file_open(UTF8ToString($0)); }, url );
|
||||
|
||||
// TODO rebuild local path in ramdisk relative to getcwd()
|
||||
char fname[MICROPY_ALLOC_PATH_MAX];
|
||||
|
||||
snprintf(fname, sizeof(fname), "cache_%d", fidx);
|
||||
return fileno( fopen(fname,"r") );
|
||||
}
|
||||
if ( (strlen(url)>6) && (url[4]==':' || url[5]==':') ) {
|
||||
fprintf(stderr," -> remote host[%s]\n", url);
|
||||
int fidx = EM_ASM_INT({return wasm_file_open(UTF8ToString($0)); }, url );
|
||||
char fname[20];
|
||||
snprintf(fname, sizeof(fname), "cache_%d", fidx);
|
||||
return fileno( fopen(fname,"r") );
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -29,7 +29,7 @@ var Module = {};
|
||||
var mainProgram = function()
|
||||
{
|
||||
mp_js_init = Module.cwrap('mp_js_init', 'null', ['number']);
|
||||
mp_js_do_str = Module.cwrap('mp_js_do_str', 'null', ['string']);
|
||||
mp_js_do_str = Module.cwrap('mp_js_do_str', 'number', ['string']);
|
||||
mp_js_init_repl = Module.cwrap('mp_js_init_repl', 'null', ['null']);
|
||||
mp_js_process_char = Module.cwrap('mp_js_process_char', 'number', ['number']);
|
||||
|
||||
@ -69,7 +69,7 @@ var mainProgram = function()
|
||||
}
|
||||
});
|
||||
} else {
|
||||
mp_js_do_str(contents);
|
||||
process.exitCode = mp_js_do_str(contents);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user