Reset JavaScript port to upstream state

This commit is contained in:
Themba Dube 2019-08-08 14:19:29 -04:00
parent 4ffae4c588
commit b3f0b9244e
24 changed files with 54 additions and 342036 deletions

View File

@ -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

View File

@ -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)
}

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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>

View File

@ -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() + "&timestamp=" + 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>

File diff suppressed because one or more lines are too long

View File

@ -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,7 +90,7 @@ 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
@ -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);

View File

@ -1,2 +0,0 @@
py/modbuiltins.c
py/makeqstrdata.py

View File

@ -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)

View File

@ -1 +0,0 @@
__dict__ = globals()

View File

@ -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() )

View File

@ -1,10 +0,0 @@
import sys
import builtins
for name in ("sys", "__main__", "builtins"):
sys.modules[name] = __import__(name)
import imp
builtins.imp = imp

View File

@ -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

View File

@ -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)

View File

@ -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)
{
}

View File

@ -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;
}

View File

@ -1,4 +0,0 @@
print("Hello World from an online module")
print("__name__","=",__name__)
print("__file__","=",__file__)

View 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;
}

View File

@ -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);
}
}
}