@@ -55,17 +55,26 @@ def force_str(string):
5555
5656
5757def parse_literals (code ):
58- JERRY_SNAPSHOT_VERSION = 7
58+ JERRY_SNAPSHOT_VERSION = 8
59+ JERRY_SNAPSHOT_MAGIC = 0x5952524A
5960
6061 literals = set ()
61-
62- header = struct .unpack ('IIII' , code [0 :16 ])
63- if header [0 ] != JERRY_SNAPSHOT_VERSION :
62+ # header format:
63+ # uint32_t magic
64+ # uint32_t version
65+ # uint32_t global opts
66+ # uint32_t literal table offset
67+ header = struct .unpack ('I' * 4 , code [0 :4 * 4 ])
68+ if header [0 ] != JERRY_SNAPSHOT_MAGIC :
69+ print ('Incorrect snapshot format! Magic number is incorrect' )
70+ exit (1 )
71+ if header [1 ] != JERRY_SNAPSHOT_VERSION :
6472 print ('Please check jerry snapshot version (Last confirmed: %d)'
6573 % JERRY_SNAPSHOT_VERSION )
6674 exit (1 )
6775
68- code_ptr = header [1 ] + 8
76+ code_ptr = header [3 ] + 4
77+
6978 while code_ptr < len (code ):
7079 length = struct .unpack ('H' , code [code_ptr : code_ptr + 2 ])[0 ]
7180 code_ptr = code_ptr + 2
@@ -117,6 +126,25 @@ def parse_literals(code):
117126
118127MAGIC_STRINGS_HEADER = '#define JERRY_MAGIC_STRING_ITEMS \\ \n '
119128
129+ MODULE_SNAPSHOT_VARIABLES_H = '''
130+ extern const char module_{NAME}[];
131+ extern const uint32_t module_{NAME}_idx;
132+ '''
133+
134+ MODULE_SNAPSHOT_VARIABLES_C = '''
135+ #define MODULE_{NAME}_IDX ({IDX})
136+ const char module_{NAME}[] = "{NAME}";
137+ const uint32_t module_{NAME}_idx = MODULE_{NAME}_IDX;
138+ '''
139+
140+ NATIVE_SNAPSHOT_STRUCT_H = '''
141+ typedef struct {
142+ const char* name;
143+ const uint32_t idx;
144+ } iotjs_js_module;
145+
146+ extern const iotjs_js_module natives[];
147+ '''
120148
121149MODULE_VARIABLES_H = '''
122150extern const char {NAME}_n[];
@@ -168,6 +196,28 @@ def format_code(code, indent):
168196 return "\n " .join (lines )
169197
170198
199+ def merge_snapshots (snapshot_infos , snapshot_merger ):
200+ output_path = fs .join (path .SRC_ROOT , 'js' ,'merged.modules' )
201+ cmd = [snapshot_merger , "merge" , "-o" , output_path ]
202+ cmd .extend ([item ['path' ] for item in snapshot_infos ])
203+
204+ ret = subprocess .call (cmd )
205+
206+ if ret != 0 :
207+ msg = "Failed to merge %s: - %d" % (snapshot_infos , ret )
208+ print ("%s%s%s" % ("\033 [1;31m" , msg , "\033 [0m" ))
209+ exit (1 )
210+
211+ for item in snapshot_infos :
212+ fs .remove (item ['path' ])
213+
214+ with open (output_path , 'rb' ) as snapshot :
215+ code = snapshot .read ()
216+
217+ fs .remove (output_path )
218+ return code
219+
220+
171221def get_snapshot_contents (module_name , snapshot_generator ):
172222 """ Convert the given module with the snapshot generator
173223 and return the resulting bytes.
@@ -189,18 +239,15 @@ def get_snapshot_contents(module_name, snapshot_generator):
189239 "--save-snapshot-for-eval" ,
190240 snapshot_path ,
191241 wrapped_path ])
242+
243+ fs .remove (wrapped_path )
192244 if ret != 0 :
193245 msg = "Failed to dump %s: - %d" % (js_path , ret )
194246 print ("%s%s%s" % ("\033 [1;31m" , msg , "\033 [0m" ))
247+ fs .remove (snapshot_path )
195248 exit (1 )
196249
197- with open (snapshot_path , 'rb' ) as snapshot :
198- code = snapshot .read ()
199-
200- fs .remove (wrapped_path )
201- fs .remove (snapshot_path )
202-
203- return code
250+ return snapshot_path
204251
205252
206253def get_js_contents (name , is_debug_mode = False ):
@@ -216,7 +263,8 @@ def get_js_contents(name, is_debug_mode=False):
216263 return code
217264
218265
219- def js2c (buildtype , no_snapshot , js_modules , js_dumper , verbose = False ):
266+ def js2c (buildtype , no_snapshot , js_modules , js_dumper , snapshot_merger ,
267+ verbose = False ):
220268 is_debug_mode = buildtype == "debug"
221269 magic_string_set = set ()
222270
@@ -236,33 +284,61 @@ def js2c(buildtype, no_snapshot, js_modules, js_dumper, verbose=False):
236284 fout_c .write (LICENSE )
237285 fout_c .write (HEADER2 )
238286
239- for name in sorted (js_modules ):
287+ snapshot_infos = []
288+ for idx , name in enumerate (sorted (js_modules )):
240289 if verbose :
241290 print ('Processing module: %s' % name )
242291
243292 if no_snapshot :
244293 code = get_js_contents (name , is_debug_mode )
294+ code_string = format_code (code , 1 )
295+
296+ fout_h .write (MODULE_VARIABLES_H .format (NAME = name ))
297+ fout_c .write (MODULE_VARIABLES_C .format (NAME = name ,
298+ NAME_UPPER = name .upper (),
299+ SIZE = len (code ),
300+ CODE = code_string ))
245301 else :
246- code = get_snapshot_contents (name , js_dumper )
247- magic_string_set |= parse_literals (code )
302+ code_path = get_snapshot_contents (name , js_dumper )
303+ info = {'name' : name , 'path' : code_path , 'idx' : idx }
304+ snapshot_infos .append (info )
305+
306+ fout_h .write (MODULE_SNAPSHOT_VARIABLES_H .format (NAME = name ))
307+ fout_c .write (MODULE_SNAPSHOT_VARIABLES_C .format (NAME = name ,
308+ IDX = idx ))
248309
310+
311+ if no_snapshot :
312+ modules_struct = [
313+ ' {{ {0}_n, {0}_s, SIZE_{1} }},' .format (name , name .upper ())
314+ for name in sorted (js_modules )
315+ ]
316+ modules_struct .append (' { NULL, NULL, 0 }' )
317+ else :
318+ code = merge_snapshots (snapshot_infos , snapshot_merger )
249319 code_string = format_code (code , 1 )
320+ magic_string_set |= parse_literals (code )
250321
322+ name = 'iotjs_js_modules'
251323 fout_h .write (MODULE_VARIABLES_H .format (NAME = name ))
252324 fout_c .write (MODULE_VARIABLES_C .format (NAME = name ,
253325 NAME_UPPER = name .upper (),
254326 SIZE = len (code ),
255327 CODE = code_string ))
328+ modules_struct = [
329+ ' {{ module_{0}, MODULE_{0}_IDX }},' .format (info ['name' ])
330+ for info in snapshot_infos
331+ ]
332+ modules_struct .append (' { NULL, 0 }' )
333+
334+ if no_snapshot :
335+ native_struct_h = NATIVE_STRUCT_H
336+ else :
337+ native_struct_h = NATIVE_SNAPSHOT_STRUCT_H
256338
257- fout_h .write (NATIVE_STRUCT_H )
339+ fout_h .write (native_struct_h )
258340 fout_h .write (FOOTER1 )
259341
260- modules_struct = [
261- ' {{ {0}_n, {0}_s, SIZE_{1} }},' .format (name , name .upper ())
262- for name in sorted (js_modules )
263- ]
264- modules_struct .append (' { NULL, NULL, 0 }' )
265-
266342 fout_c .write (NATIVE_STRUCT_C .format (MODULES = "\n " .join (modules_struct )))
267343 fout_c .write (EMPTY_LINE )
268344
@@ -294,12 +370,14 @@ def js2c(buildtype, no_snapshot, js_modules, js_dumper, verbose=False):
294370 parser .add_argument ('--snapshot-generator' , default = None ,
295371 help = 'Executable to use for generating snapshots from the JS files. '
296372 'If not specified the JS files will be directly processed.' )
373+ parser .add_argument ('--snapshot-merger' , default = None ,
374+ help = 'Executable to use to merge snapshots.' )
297375 parser .add_argument ('-v' , '--verbose' , default = False ,
298376 help = 'Enable verbose output.' )
299377
300378 options = parser .parse_args ()
301379
302- if not options .snapshot_generator :
380+ if not options .snapshot_generator or not options . snapshot_merger :
303381 print ('Converting JS modules to C arrays (no snapshot)' )
304382 no_snapshot = True
305383 else :
@@ -308,4 +386,4 @@ def js2c(buildtype, no_snapshot, js_modules, js_dumper, verbose=False):
308386
309387 modules = options .modules .replace (',' , ' ' ).split ()
310388 js2c (options .buildtype , no_snapshot , modules , options .snapshot_generator ,
311- options .verbose )
389+ options .snapshot_merger , options . verbose )
0 commit comments