183
183
}
184
184
185
185
186
- def listdir (path ) :
186
+ def listdir (path : str ) -> list :
187
187
return [os .path .join (path , p ) for p in os .listdir (path )]
188
188
189
189
190
- class assemble (setuptools .Command ):
191
- user_options = []
192
-
193
- def initialize_options (self ):
194
- pass
190
+ def is_x86 () -> bool :
191
+ return platform .machine () in ("x86" , "i386" , "i686" , "AMD64" , "x86_64" )
195
192
196
- def finalize_options (self ):
197
- pass
198
193
199
- def run (self ):
200
- for source in listdir ("wasmpy/x86" ) + listdir ("wasmpy/x86/64" ):
201
- if os .path .isdir (source ):
202
- continue
194
+ class assemble (setuptools .Command ):
195
+ user_options = [("targets=" , "T" , None )]
203
196
204
- # assemble x86 instructions
205
- if os .path .splitext (source )[1 ].lower () == ".s" :
206
- subprocess .call (
207
- [
208
- "as" ,
209
- source ,
210
- "-o" ,
211
- os .path .splitext (source )[0 ] + ".o" ,
212
- ]
213
- )
197
+ def initialize_options (self ):
198
+ if is_x86 ():
199
+ if struct .calcsize ("P" ) == 4 :
200
+ self .targets = "x86"
214
201
215
- if platform .system () == "Linux" :
216
- subprocess .call (
217
- [
218
- "ld" ,
219
- "--oformat" ,
220
- "binary" ,
221
- os .path .splitext (source )[0 ] + ".o" ,
222
- "-o" ,
223
- os .path .splitext (source )[0 ],
224
- ]
225
- )
202
+ else :
203
+ self .targets = "x86_64"
226
204
227
- elif platform .system () == "Windows" :
228
- subprocess .call (
229
- [
230
- "ld" ,
231
- "-T" ,
232
- "NUL" ,
233
- "--image-base" ,
234
- "0" ,
235
- os .path .splitext (source )[0 ] + ".o" ,
236
- "-o" ,
237
- os .path .splitext (source )[0 ] + ".tmp" ,
238
- ]
239
- )
240
- subprocess .call (
241
- [
242
- "objcopy" ,
243
- "-O" ,
244
- "binary" ,
245
- "-j" ,
246
- ".text" ,
247
- os .path .splitext (source )[0 ] + ".tmp" ,
248
- os .path .splitext (source )[0 ],
249
- ]
250
- )
205
+ else :
206
+ raise ValueError ("Unknown architecture" )
251
207
252
- for source in listdir ("wasmpy/x86/32" ):
253
- if os .path .isdir (source ):
254
- continue
208
+ def finalize_options (self ):
209
+ self .targets = self .targets .split ("," )
210
+ for target in self .targets :
211
+ if target not in os .listdir ("wasmpy/arch" ) or os .path .isfile (
212
+ f"wasmpy/{ target } "
213
+ ):
214
+ raise ValueError (f"Unknown architecture: { target } " )
255
215
256
- # assemble x86 32 bit specific instructions
257
- if os .path .splitext (source )[1 ].lower () == ".s" :
258
- subprocess .call (
259
- [
260
- "as" ,
261
- "--32" ,
262
- source ,
263
- "-o" ,
264
- os .path .splitext (source )[0 ] + ".o" ,
265
- ]
266
- )
216
+ def run (self ):
217
+ args = {
218
+ "x86_64" : [
219
+ ["as" , "-o" ],
220
+ ["ld" , "--oformat" , "binary" , "-o" ],
221
+ ["ld" , "-T" , "NUL" , "--image-base" , "0" , "-o" ],
222
+ ["objcopy" , "-O" , "binary" , "-j" , ".text" ],
223
+ ]
224
+ }
225
+
226
+ args ["x86" ] = [i .copy () for i in args ["x86_64" ]]
227
+ args ["x86" ][0 ].insert (1 , "--32" )
228
+ args ["x86" ][1 ].insert (1 , "-melf_i386" )
229
+ args ["x86" ][2 ].insert (1 , "-mi386pe" )
230
+
231
+ for target in self .targets :
232
+ arg = args [target ]
233
+ for source in listdir (f"wasmpy/arch/{ target } " ):
234
+ if os .path .isdir (source ):
235
+ continue
267
236
268
- if platform .system () == "Linux" :
269
- subprocess .call (
270
- [
271
- "ld" ,
272
- "-melf_i386" ,
273
- "--oformat" ,
274
- "binary" ,
275
- os .path .splitext (source )[0 ] + ".o" ,
276
- "-o" ,
277
- os .path .splitext (source )[0 ],
278
- ]
279
- )
237
+ if os .path .splitext (source )[1 ].lower () == ".s" :
238
+ name = os .path .splitext (source )[0 ]
239
+ cmd = arg [0 ] + [name + ".o" , source ]
240
+ subprocess .call (cmd )
280
241
281
- elif platform .system () == "Windows" :
282
- subprocess .call (
283
- [
284
- "ld" ,
285
- "-mi386pe" ,
286
- "-T" ,
287
- "NUL" ,
288
- "--image-base" ,
289
- "0" ,
290
- os .path .splitext (source )[0 ] + ".o" ,
291
- "-o" ,
292
- os .path .splitext (source )[0 ] + ".tmp" ,
293
- ]
294
- )
242
+ if platform .system () == "Linux" :
243
+ cmd = arg [1 ] + [name , name + ".o" ]
244
+ subprocess .call (cmd )
295
245
296
- subprocess .call (
297
- [
298
- "objcopy" ,
299
- "-O" ,
300
- "binary" ,
301
- "-j" ,
302
- ".text" ,
303
- os .path .splitext (source )[0 ] + ".tmp" ,
304
- os .path .splitext (source )[0 ],
305
- ]
306
- )
246
+ elif platform .system () == "Windows" :
247
+ cmd = arg [2 ] + [name + ".tmp" , name + ".o" ]
248
+ subprocess .call (cmd )
249
+ cmd = arg [3 ] + [name + ".tmp" , name ]
250
+ subprocess .call (cmd )
307
251
308
252
309
253
class tidy (setuptools .Command ):
@@ -316,19 +260,19 @@ def finalize_options(self):
316
260
pass
317
261
318
262
def run (self ):
319
- if os .path .exists ("wasmpy/x86/lib/opcodes.cpp" ):
320
- os .remove ("wasmpy/x86/lib/opcodes.cpp" )
321
-
322
- for file in (
323
- listdir ("wasmpy/x86" )
324
- + listdir ("wasmpy/x86/64" )
325
- + listdir ("wasmpy/x86/32" )
326
- ):
327
- if os .path .isdir (file ):
263
+ for machine in os .listdir ("wasmpy/arch" ):
264
+ if os .path .isfile ("wasmpy/arch/" + machine ):
328
265
continue
329
266
330
- if os .path .splitext (file )[1 ] != ".s" :
331
- os .remove (file )
267
+ if os .path .exists (f"wasmpy/arch/{ machine } /lib/opcodes.cpp" ):
268
+ os .remove (f"wasmpy/arch/{ machine } /lib/opcodes.cpp" )
269
+
270
+ for file in listdir (f"wasmpy/arch/{ machine } " ):
271
+ if os .path .isdir (file ):
272
+ continue
273
+
274
+ if os .path .splitext (file )[1 ] != ".s" :
275
+ os .remove (file )
332
276
333
277
334
278
class gen_opcodes (setuptools .Command ):
@@ -347,7 +291,6 @@ def run(self):
347
291
os .path .join (os .path .dirname (__file__ ), "wasmpy" , "opcodes.json" )
348
292
) as fp :
349
293
data = json .load (fp )
350
- consumes = data ["consumes" ]
351
294
for group in data ["opcodes" ]:
352
295
opcodes .update (
353
296
dict (
@@ -361,9 +304,13 @@ def run(self):
361
304
)
362
305
)
363
306
364
- with open ("wasmpy/x86/lib/opcodes.cpp" , "w+" ) as out :
365
- bits = struct .calcsize ("P" )
307
+ if struct .calcsize ("P" ) == 4 :
308
+ machine = "x86"
309
+
310
+ else :
311
+ machine = "x86_64"
366
312
313
+ with open (f"wasmpy/arch/{ machine } /lib/opcodes.cpp" , "w+" ) as out :
367
314
out .writelines (
368
315
(
369
316
"// auto-generated\n \n " ,
@@ -376,13 +323,7 @@ def run(self):
376
323
)
377
324
)
378
325
379
- if bits == 8 :
380
- extra = listdir ("wasmpy/x86/64" )
381
-
382
- elif bits == 4 :
383
- extra = listdir ("wasmpy/x86/32" )
384
-
385
- for file in listdir ("wasmpy/x86" ) + extra :
326
+ for file in listdir (f"wasmpy/arch/{ machine } " ):
386
327
if os .path .isdir (file ):
387
328
continue
388
329
@@ -407,7 +348,7 @@ def run(self):
407
348
408
349
out .write ("default:\n \t \t break;\n \t }\n \t return insts;\n }\n \n " )
409
350
410
- for file in listdir ("wasmpy/x86" ) + extra :
351
+ for file in listdir (f "wasmpy/arch/ { machine } " ) :
411
352
if os .path .isdir (file ):
412
353
continue
413
354
@@ -451,11 +392,20 @@ def run(self):
451
392
),
452
393
]
453
394
454
- if platform .machine () in ("x86" , "i386" , "i686" , "AMD64" , "x86_64" ):
395
+ if is_x86 ():
396
+ if struct .calcsize ("P" ) == 4 :
397
+ machine = "x86"
398
+
399
+ else :
400
+ machine = "x86_64"
401
+
455
402
ext .append (
456
403
setuptools .Extension (
457
404
"wasmpy.nativelib" ,
458
- sources = ["wasmpy/x86/lib/lib.cpp" , "wasmpy/x86/lib/opcodes.cpp" ],
405
+ sources = [
406
+ f"wasmpy/arch/{ machine } /lib/lib.cpp" ,
407
+ f"wasmpy/arch/{ machine } /lib/opcodes.cpp" ,
408
+ ],
459
409
py_limited_api = True ,
460
410
)
461
411
)
0 commit comments