Răsfoiți Sursa

Merge pull request #64 from SummerGGift/Branch_b7aafc601ecb9756a1e54d9b5b092d6b7554b1e2

【完善】uzlib 模块编译出错以及删除多余 mpy 文件
朱天龙 (Armink) 6 ani în urmă
părinte
comite
a10e53d69a
7 a modificat fișierele cu 152 adăugiri și 274 ștergeri
  1. 1 0
      README.md
  2. 3 117
      extmod/uzlib/tinf.h
  3. 2 2
      extmod/uzlib/tinfgzip.c
  4. 139 33
      extmod/uzlib/tinflate.c
  5. 2 2
      extmod/uzlib/tinfzlib.c
  6. 0 120
      port/_frozen_mpy.c
  7. 5 0
      port/modffi.c

+ 1 - 0
README.md

@@ -43,6 +43,7 @@ RT-Thread MicroPython  遵循 MIT 许可,详见 `LICENSE` 文件。
 
 - 需要使用 **RT-Thread 3.0** 以上版本。
 - 在 `menuconfig` 选项中选择 `Micropython` 的 `latest` 版本。
+- 目前 `System Module` 下的 `ffi` 模块只支持 GCC 工具链,且需要在链接脚本中添加相关段信息。 
 
 ## 5、开发资源
 

+ 3 - 117
extmod/uzlib/tinf.h

@@ -1,117 +1,3 @@
-/*
- * uzlib  -  tiny deflate/inflate library (deflate, gzip, zlib)
- *
- * Copyright (c) 2003 by Joergen Ibsen / Jibz
- * All Rights Reserved
- * http://www.ibsensoftware.com/
- *
- * Copyright (c) 2014-2016 by Paul Sokolovsky
- */
-
-#ifndef TINF_H_INCLUDED
-#define TINF_H_INCLUDED
-
-#include <stdint.h>
-
-/* calling convention */
-#ifndef TINFCC
- #ifdef __WATCOMC__
-  #define TINFCC __cdecl
- #else
-  #define TINFCC
- #endif
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* ok status, more data produced */
-#define TINF_OK             0
-/* end of compressed stream reached */
-#define TINF_DONE           1
-#define TINF_DATA_ERROR    (-3)
-#define TINF_CHKSUM_ERROR  (-4)
-#define TINF_DICT_ERROR    (-5)
-
-/* checksum types */
-#define TINF_CHKSUM_NONE  0
-#define TINF_CHKSUM_ADLER 1
-#define TINF_CHKSUM_CRC   2
-
-/* data structures */
-
-typedef struct {
-   unsigned short table[16];  /* table of code length counts */
-   unsigned short trans[288]; /* code -> symbol translation table */
-} TINF_TREE;
-
-struct TINF_DATA;
-typedef struct TINF_DATA {
-   const unsigned char *source;
-   /* If source above is NULL, this function will be used to read
-      next byte from source stream */
-   unsigned char (*readSource)(struct TINF_DATA *data);
-
-   unsigned int tag;
-   unsigned int bitcount;
-
-    /* Buffer start */
-    unsigned char *destStart;
-    /* Buffer total size */
-    unsigned int destSize;
-    /* Current pointer in buffer */
-    unsigned char *dest;
-    /* Remaining bytes in buffer */
-    unsigned int destRemaining;
-
-    /* Accumulating checksum */
-    unsigned int checksum;
-    char checksum_type;
-
-    int btype;
-    int bfinal;
-    unsigned int curlen;
-    int lzOff;
-    unsigned char *dict_ring;
-    unsigned int dict_size;
-    unsigned int dict_idx;
-
-   TINF_TREE ltree; /* dynamic length/symbol tree */
-   TINF_TREE dtree; /* dynamic distance tree */
-} TINF_DATA;
-
-#define TINF_PUT(d, c) \
-    { \
-        *d->dest++ = c; \
-        if (d->dict_ring) { d->dict_ring[d->dict_idx++] = c; if (d->dict_idx == d->dict_size) d->dict_idx = 0; } \
-    }
-
-unsigned char TINFCC uzlib_get_byte(TINF_DATA *d);
-
-/* Decompression API */
-
-void TINFCC uzlib_init(void);
-void TINFCC uzlib_uncompress_init(TINF_DATA *d, void *dict, unsigned int dictLen);
-int  TINFCC uzlib_uncompress(TINF_DATA *d);
-int  TINFCC uzlib_uncompress_chksum(TINF_DATA *d);
-
-int TINFCC uzlib_zlib_parse_header(TINF_DATA *d);
-int TINFCC uzlib_gzip_parse_header(TINF_DATA *d);
-
-/* Compression API */
-
-void TINFCC uzlib_compress(void *data, const uint8_t *src, unsigned slen);
-
-/* Checksum API */
-
-/* prev_sum is previous value for incremental computation, 1 initially */
-uint32_t TINFCC uzlib_adler32(const void *data, unsigned int length, uint32_t prev_sum);
-/* crc is previous value for incremental computation, 0xffffffff initially */
-uint32_t TINFCC uzlib_crc32(const void *data, unsigned int length, uint32_t crc);
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* TINF_H_INCLUDED */
+/* Compatibility header for the original tinf lib/older versions of uzlib.
+   Note: may be removed in the future, please migrate to uzlib.h. */
+#include "uzlib.h"

+ 2 - 2
extmod/uzlib/tinfgzip.c

@@ -1,12 +1,12 @@
 /*
- * tinfgzip  -  tiny gzip decompressor
+ * uzlib  -  tiny deflate/inflate library (deflate, gzip, zlib)
  *
  * Copyright (c) 2003 by Joergen Ibsen / Jibz
  * All Rights Reserved
  *
  * http://www.ibsensoftware.com/
  *
- * Copyright (c) 2014-2016 by Paul Sokolovsky
+ * Copyright (c) 2014-2018 by Paul Sokolovsky
  *
  * This software is provided 'as-is', without any express
  * or implied warranty.  In no event will the authors be

+ 139 - 33
extmod/uzlib/tinflate.c

@@ -1,11 +1,11 @@
 /*
- * tinflate  -  tiny inflate
+ * uzlib  -  tiny deflate/inflate library (deflate, gzip, zlib)
  *
  * Copyright (c) 2003 by Joergen Ibsen / Jibz
  * All Rights Reserved
  * http://www.ibsensoftware.com/
  *
- * Copyright (c) 2014-2016 by Paul Sokolovsky
+ * Copyright (c) 2014-2018 by Paul Sokolovsky
  *
  * This software is provided 'as-is', without any express
  * or implied warranty.  In no event will the authors be
@@ -35,6 +35,15 @@
 #include <assert.h>
 #include "tinf.h"
 
+#define UZLIB_DUMP_ARRAY(heading, arr, size) \
+    { \
+        printf("%s", heading); \
+        for (int i = 0; i < size; ++i) { \
+            printf(" %d", (arr)[i]); \
+        } \
+        printf("\n"); \
+    }
+
 uint32_t tinf_get_le_uint32(TINF_DATA *d);
 uint32_t tinf_get_be_uint32(TINF_DATA *d);
 
@@ -149,6 +158,13 @@ static void tinf_build_tree(TINF_TREE *t, const unsigned char *lengths, unsigned
    /* scan symbol lengths, and sum code length counts */
    for (i = 0; i < num; ++i) t->table[lengths[i]]++;
 
+   #if UZLIB_CONF_DEBUG_LOG >= 2
+   UZLIB_DUMP_ARRAY("codelen counts:", t->table, TINF_ARRAY_SIZE(t->table));
+   #endif
+
+   /* In the lengths array, 0 means unused code. So, t->table[0] now contains
+      number of unused codes. But table's purpose is to contain # of codes of
+      particular length, and there're 0 codes of length 0. */
    t->table[0] = 0;
 
    /* compute offset table for distribution sort */
@@ -158,6 +174,10 @@ static void tinf_build_tree(TINF_TREE *t, const unsigned char *lengths, unsigned
       sum += t->table[i];
    }
 
+   #if UZLIB_CONF_DEBUG_LOG >= 2
+   UZLIB_DUMP_ARRAY("codelen offsets:", offs, TINF_ARRAY_SIZE(offs));
+   #endif
+
    /* create code->symbol translation table (symbols sorted by code) */
    for (i = 0; i < num; ++i)
    {
@@ -171,10 +191,28 @@ static void tinf_build_tree(TINF_TREE *t, const unsigned char *lengths, unsigned
 
 unsigned char uzlib_get_byte(TINF_DATA *d)
 {
-    if (d->source) {
+    /* If end of source buffer is not reached, return next byte from source
+       buffer. */
+    if (d->source < d->source_limit) {
         return *d->source++;
     }
-    return d->readSource(d);
+
+    /* Otherwise if there's callback and we haven't seen EOF yet, try to
+       read next byte using it. (Note: the callback can also update ->source
+       and ->source_limit). */
+    if (d->readSource && !d->eof) {
+        int val = d->readSource(d);
+        if (val >= 0) {
+            return (unsigned char)val;
+        }
+    }
+
+    /* Otherwise, we hit EOF (either from ->readSource() or from exhaustion
+       of the buffer), and it will be "sticky", i.e. further calls to this
+       function will end up here too. */
+    d->eof = true;
+
+    return 0;
 }
 
 uint32_t tinf_get_le_uint32(TINF_DATA *d)
@@ -182,7 +220,7 @@ uint32_t tinf_get_le_uint32(TINF_DATA *d)
     uint32_t val = 0;
     int i;
     for (i = 4; i--;) {
-        val = val >> 8 | uzlib_get_byte(d) << 24;
+        val = val >> 8 | ((uint32_t)uzlib_get_byte(d)) << 24;
     }
     return val;
 }
@@ -245,21 +283,31 @@ static int tinf_decode_symbol(TINF_DATA *d, TINF_TREE *t)
 
       cur = 2*cur + tinf_getbit(d);
 
-      ++len;
+      if (++len == TINF_ARRAY_SIZE(t->table)) {
+         return TINF_DATA_ERROR;
+      }
 
       sum += t->table[len];
       cur -= t->table[len];
 
    } while (cur >= 0);
 
-   return t->trans[sum + cur];
+   sum += cur;
+   #if UZLIB_CONF_PARANOID_CHECKS
+   if (sum < 0 || sum >= TINF_ARRAY_SIZE(t->trans)) {
+      return TINF_DATA_ERROR;
+   }
+   #endif
+
+   return t->trans[sum];
 }
 
 /* given a data stream, decode dynamic trees from it */
-static void tinf_decode_trees(TINF_DATA *d, TINF_TREE *lt, TINF_TREE *dt)
+static int tinf_decode_trees(TINF_DATA *d, TINF_TREE *lt, TINF_TREE *dt)
 {
+   /* code lengths for 288 literal/len symbols and 32 dist symbols */
    unsigned char lengths[288+32];
-   unsigned int hlit, hdist, hclen;
+   unsigned int hlit, hdist, hclen, hlimit;
    unsigned int i, num, length;
 
    /* get 5 bits HLIT (257-286) */
@@ -286,53 +334,75 @@ static void tinf_decode_trees(TINF_DATA *d, TINF_TREE *lt, TINF_TREE *dt)
    tinf_build_tree(lt, lengths, 19);
 
    /* decode code lengths for the dynamic trees */
-   for (num = 0; num < hlit + hdist; )
+   hlimit = hlit + hdist;
+   for (num = 0; num < hlimit; )
    {
       int sym = tinf_decode_symbol(d, lt);
+      unsigned char fill_value = 0;
+      int lbits, lbase = 3;
+
+      /* error decoding */
+      if (sym < 0) return sym;
 
       switch (sym)
       {
       case 16:
          /* copy previous code length 3-6 times (read 2 bits) */
-         {
-            unsigned char prev = lengths[num - 1];
-            for (length = tinf_read_bits(d, 2, 3); length; --length)
-            {
-               lengths[num++] = prev;
-            }
-         }
+         if (num == 0) return TINF_DATA_ERROR;
+         fill_value = lengths[num - 1];
+         lbits = 2;
          break;
       case 17:
          /* repeat code length 0 for 3-10 times (read 3 bits) */
-         for (length = tinf_read_bits(d, 3, 3); length; --length)
-         {
-            lengths[num++] = 0;
-         }
+         lbits = 3;
          break;
       case 18:
          /* repeat code length 0 for 11-138 times (read 7 bits) */
-         for (length = tinf_read_bits(d, 7, 11); length; --length)
-         {
-            lengths[num++] = 0;
-         }
+         lbits = 7;
+         lbase = 11;
          break;
       default:
          /* values 0-15 represent the actual code lengths */
          lengths[num++] = sym;
-         break;
+         /* continue the for loop */
+         continue;
       }
+
+      /* special code length 16-18 are handled here */
+      length = tinf_read_bits(d, lbits, lbase);
+      if (num + length > hlimit) return TINF_DATA_ERROR;
+      for (; length; --length)
+      {
+         lengths[num++] = fill_value;
+      }
+   }
+
+   #if UZLIB_CONF_DEBUG_LOG >= 2
+   printf("lit code lengths (%d):", hlit);
+   UZLIB_DUMP_ARRAY("", lengths, hlit);
+   printf("dist code lengths (%d):", hdist);
+   UZLIB_DUMP_ARRAY("", lengths + hlit, hdist);
+   #endif
+
+   #if UZLIB_CONF_PARANOID_CHECKS
+   /* Check that there's "end of block" symbol */
+   if (lengths[256] == 0) {
+      return TINF_DATA_ERROR;
    }
+   #endif
 
    /* build dynamic trees */
    tinf_build_tree(lt, lengths, hlit);
    tinf_build_tree(dt, lengths + hlit, hdist);
+
+   return TINF_OK;
 }
 
 /* ----------------------------- *
  * -- block inflate functions -- *
  * ----------------------------- */
 
-/* given a stream and two trees, inflate a block of data */
+/* given a stream and two trees, inflate next byte of output */
 static int tinf_inflate_block_data(TINF_DATA *d, TINF_TREE *lt, TINF_TREE *dt)
 {
     if (d->curlen == 0) {
@@ -341,6 +411,10 @@ static int tinf_inflate_block_data(TINF_DATA *d, TINF_TREE *lt, TINF_TREE *dt)
         int sym = tinf_decode_symbol(d, lt);
         //printf("huff sym: %02x\n", sym);
 
+        if (d->eof) {
+            return TINF_DATA_ERROR;
+        }
+
         /* literal byte */
         if (sym < 256) {
             TINF_PUT(d, sym);
@@ -354,21 +428,45 @@ static int tinf_inflate_block_data(TINF_DATA *d, TINF_TREE *lt, TINF_TREE *dt)
 
         /* substring from sliding dictionary */
         sym -= 257;
+        if (sym >= 29) {
+            return TINF_DATA_ERROR;
+        }
+
         /* possibly get more bits from length code */
         d->curlen = tinf_read_bits(d, length_bits[sym], length_base[sym]);
 
         dist = tinf_decode_symbol(d, dt);
+        if (dist >= 30) {
+            return TINF_DATA_ERROR;
+        }
+
         /* possibly get more bits from distance code */
         offs = tinf_read_bits(d, dist_bits[dist], dist_base[dist]);
+
+        /* calculate and validate actual LZ offset to use */
         if (d->dict_ring) {
             if (offs > d->dict_size) {
                 return TINF_DICT_ERROR;
             }
+            /* Note: unlike full-dest-in-memory case below, we don't
+               try to catch offset which points to not yet filled
+               part of the dictionary here. Doing so would require
+               keeping another variable to track "filled in" size
+               of the dictionary. Appearance of such an offset cannot
+               lead to accessing memory outside of the dictionary
+               buffer, and clients which don't want to leak unrelated
+               information, should explicitly initialize dictionary
+               buffer passed to uzlib. */
+
             d->lzOff = d->dict_idx - offs;
             if (d->lzOff < 0) {
                 d->lzOff += d->dict_size;
             }
         } else {
+            /* catch trying to point before the start of dest buffer */
+            if (offs > d->dest - d->destStart) {
+                return TINF_DATA_ERROR;
+            }
             d->lzOff = -offs;
         }
     }
@@ -387,7 +485,7 @@ static int tinf_inflate_block_data(TINF_DATA *d, TINF_TREE *lt, TINF_TREE *dt)
     return TINF_OK;
 }
 
-/* inflate an uncompressed block of data */
+/* inflate next byte from uncompressed block of data */
 static int tinf_inflate_uncompressed_block(TINF_DATA *d)
 {
     if (d->curlen == 0) {
@@ -440,6 +538,7 @@ void uzlib_init(void)
 /* initialize decompression structure */
 void uzlib_uncompress_init(TINF_DATA *d, void *dict, unsigned int dictLen)
 {
+   d->eof = 0;
    d->bitcount = 0;
    d->bfinal = 0;
    d->btype = -1;
@@ -449,7 +548,7 @@ void uzlib_uncompress_init(TINF_DATA *d, void *dict, unsigned int dictLen)
    d->curlen = 0;
 }
 
-/* inflate next byte of compressed stream */
+/* inflate next output bytes from compressed stream */
 int uzlib_uncompress(TINF_DATA *d)
 {
     do {
@@ -463,14 +562,19 @@ next_blk:
             /* read block type (2 bits) */
             d->btype = tinf_read_bits(d, 2, 0);
 
-            //printf("Started new block: type=%d final=%d\n", d->btype, d->bfinal);
+            #if UZLIB_CONF_DEBUG_LOG >= 1
+            printf("Started new block: type=%d final=%d\n", d->btype, d->bfinal);
+            #endif
 
             if (d->btype == 1) {
                 /* build fixed huffman trees */
                 tinf_build_fixed_trees(&d->ltree, &d->dtree);
             } else if (d->btype == 2) {
                 /* decode trees from stream */
-                tinf_decode_trees(d, &d->ltree, &d->dtree);
+                res = tinf_decode_trees(d, &d->ltree, &d->dtree);
+                if (res != TINF_OK) {
+                    return res;
+                }
             }
         }
 
@@ -483,7 +587,7 @@ next_blk:
             break;
         case 1:
         case 2:
-            /* decompress block with fixed/dyanamic huffman trees */
+            /* decompress block with fixed/dynamic huffman trees */
             /* trees were decoded previously, so it's the same routine for both */
             res = tinf_inflate_block_data(d, &d->ltree, &d->dtree);
             break;
@@ -501,11 +605,13 @@ next_blk:
             return res;
         }
 
-    } while (--d->destSize);
+    } while (d->dest < d->dest_limit);
 
     return TINF_OK;
 }
 
+/* inflate next output bytes from compressed stream, updating
+   checksum, and at the end of stream, verify it */
 int uzlib_uncompress_chksum(TINF_DATA *d)
 {
     int res;

+ 2 - 2
extmod/uzlib/tinfzlib.c

@@ -1,12 +1,12 @@
 /*
- * tinfzlib  -  tiny zlib decompressor
+ * uzlib  -  tiny deflate/inflate library (deflate, gzip, zlib)
  *
  * Copyright (c) 2003 by Joergen Ibsen / Jibz
  * All Rights Reserved
  *
  * http://www.ibsensoftware.com/
  *
- * Copyright (c) 2014-2016 by Paul Sokolovsky
+ * Copyright (c) 2014-2018 by Paul Sokolovsky
  *
  * This software is provided 'as-is', without any express
  * or implied warranty.  In no event will the authors be

+ 0 - 120
port/_frozen_mpy.c

@@ -1,120 +0,0 @@
-#include "py/mpconfig.h"
-#include "py/objint.h"
-#include "py/objstr.h"
-#include "py/emitglue.h"
-
-#if MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE != 0
-#error "incompatible MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE"
-#endif
-
-#if MICROPY_LONGINT_IMPL != 2
-#error "incompatible MICROPY_LONGINT_IMPL"
-#endif
-
-#if MICROPY_PY_BUILTINS_FLOAT
-typedef struct _mp_obj_float_t {
-    mp_obj_base_t base;
-    mp_float_t value;
-} mp_obj_float_t;
-#endif
-
-#if MICROPY_PY_BUILTINS_COMPLEX
-typedef struct _mp_obj_complex_t {
-    mp_obj_base_t base;
-    mp_float_t real;
-    mp_float_t imag;
-} mp_obj_complex_t;
-#endif
-
-enum {
-    MP_QSTR_frozentest_dot_py = MP_QSTRnumber_of,
-    MP_QSTR_uPy,
-    MP_QSTR_i,
-};
-
-extern const qstr_pool_t mp_qstr_const_pool;
-const qstr_pool_t mp_qstr_frozen_const_pool = {
-    (qstr_pool_t*)&mp_qstr_const_pool, // previous pool
-    MP_QSTRnumber_of, // previous pool size
-    3, // allocated entries
-    3, // used entries
-    {
-        (const byte*)"\xfe\x0d" "frozentest.py",
-        (const byte*)"\xf9\x03" "uPy",
-        (const byte*)"\xcc\x01" "i",
-    },
-};
-
-// frozen bytecode for file frozentest.py, scope frozentest_<module>
-STATIC const byte bytecode_data_frozentest__lt_module_gt_[92] = {
-    0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d,
-    MP_QSTR__lt_module_gt_ & 0xff, MP_QSTR__lt_module_gt_ >> 8,
-    MP_QSTR_frozentest_dot_py & 0xff, MP_QSTR_frozentest_dot_py >> 8,
-    0x2a, 0x28, 0x28, 0x28, 0x2b, 0x28, 0x00, 0x00, 0xff,
-    0x1b, MP_QSTR_print & 0xff, MP_QSTR_print >> 8,
-    0x16, MP_QSTR_uPy & 0xff, MP_QSTR_uPy >> 8,
-    0x64, 0x01, 
-    0x32, 
-    0x1b, MP_QSTR_print & 0xff, MP_QSTR_print >> 8,
-    0x17, 0x00, 
-    0x64, 0x01, 
-    0x32, 
-    0x1b, MP_QSTR_print & 0xff, MP_QSTR_print >> 8,
-    0x17, 0x01, 
-    0x64, 0x01, 
-    0x32, 
-    0x1b, MP_QSTR_print & 0xff, MP_QSTR_print >> 8,
-    0x17, 0x02, 
-    0x64, 0x01, 
-    0x32, 
-    0x1b, MP_QSTR_print & 0xff, MP_QSTR_print >> 8,
-    0x14, 0xba, 0xef, 0x9a, 0x15, 
-    0x64, 0x01, 
-    0x32, 
-    0x80, 
-    0x35, 0x0f, 0x80, 
-    0x30, 
-    0x24, MP_QSTR_i & 0xff, MP_QSTR_i >> 8,
-    0x1b, MP_QSTR_print & 0xff, MP_QSTR_print >> 8,
-    0x1b, MP_QSTR_i & 0xff, MP_QSTR_i >> 8,
-    0x64, 0x01, 
-    0x32, 
-    0x81, 
-    0xe5, 
-    0x30, 
-    0x84, 
-    0xd7, 
-    0x36, 0xeb, 0x7f, 
-    0x32, 
-    0x11, 
-    0x5b, 
-};
-STATIC const mp_obj_str_t const_obj_frozentest__lt_module_gt__0 = {{&mp_type_str}, 246, 34, (const byte*)"\x61\x20\x6c\x6f\x6e\x67\x20\x73\x74\x72\x69\x6e\x67\x20\x74\x68\x61\x74\x20\x69\x73\x20\x6e\x6f\x74\x20\x69\x6e\x74\x65\x72\x6e\x65\x64"};
-STATIC const mp_obj_str_t const_obj_frozentest__lt_module_gt__1 = {{&mp_type_str}, 200, 38, (const byte*)"\x61\x20\x73\x74\x72\x69\x6e\x67\x20\x74\x68\x61\x74\x20\x68\x61\x73\x20\x75\x6e\x69\x63\x6f\x64\x65\x20\xce\xb1\xce\xb2\xce\xb3\x20\x63\x68\x61\x72\x73"};
-STATIC const mp_obj_str_t const_obj_frozentest__lt_module_gt__2 = {{&mp_type_bytes}, 57, 11, (const byte*)"\x62\x79\x74\x65\x73\x20\x31\x32\x33\x34\x01"};
-STATIC const mp_rom_obj_t const_table_data_frozentest__lt_module_gt_[3] = {
-    MP_ROM_PTR(&const_obj_frozentest__lt_module_gt__0),
-    MP_ROM_PTR(&const_obj_frozentest__lt_module_gt__1),
-    MP_ROM_PTR(&const_obj_frozentest__lt_module_gt__2),
-};
-const mp_raw_code_t raw_code_frozentest__lt_module_gt_ = {
-    .kind = MP_CODE_BYTECODE,
-    .scope_flags = 0x00,
-    .n_pos_args = 0,
-    .data.u_byte = {
-        .bytecode = bytecode_data_frozentest__lt_module_gt_,
-        .const_table = (mp_uint_t*)const_table_data_frozentest__lt_module_gt_,
-        #if MICROPY_PERSISTENT_CODE_SAVE
-        .bc_len = 92,
-        .n_obj = 3,
-        .n_raw_code = 0,
-        #endif
-    },
-};
-
-const char mp_frozen_mpy_names[] = {
-"frozentest.py\0"
-"\0"};
-const mp_raw_code_t *const mp_frozen_mpy_content[] = {
-    &raw_code_frozentest__lt_module_gt_,
-};

+ 5 - 0
port/modffi.c

@@ -36,6 +36,11 @@
 #include "py/mperrno.h"
 
 #ifdef MICROPYTHON_USING_FFI
+
+#if !defined(__GNUC__) 
+#error "The ffi module only supports GCC toolchain at present"
+#endif
+
 #include <dlfcn.h>
 #include <dlmodule.h>