Skip to content
Closed
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
ee34a80
yolo
kripken Apr 10, 2023
5b5e426
make it work
kripken Apr 10, 2023
520301b
fix
kripken Apr 10, 2023
85793ac
fix closure
kripken Apr 11, 2023
22393a4
Merge remote-tracking branch 'origin/main' into safari.bigint
kripken Apr 11, 2023
9fe22ab
fix wasm2js
kripken Apr 11, 2023
e255dad
fix test
kripken Apr 11, 2023
e1108d6
fix
kripken Apr 11, 2023
314cf8a
fix
kripken Apr 11, 2023
a52372d
cleanup
kripken Apr 11, 2023
c64adf2
more
kripken Apr 11, 2023
e7259ed
fix
kripken Apr 11, 2023
09ea912
fixflake8
kripken Apr 11, 2023
6699531
work
kripken Apr 11, 2023
d907b0e
fix
kripken Apr 12, 2023
af838e7
fix
kripken Apr 12, 2023
9aac743
fix
kripken Apr 12, 2023
5142300
work
kripken Apr 12, 2023
71ca03a
feedback
kripken Apr 12, 2023
d23687e
update test
kripken Apr 13, 2023
83165d1
fix
kripken Apr 13, 2023
0fb2458
try to fix test_dyncall_specific
kripken Apr 13, 2023
08c7170
Merge remote-tracking branch 'origin/main' into safari.bigint
kripken Apr 13, 2023
d1e4aec
fix old node version handling in common.py (maybe)
kripken Apr 13, 2023
2ae89c5
fix
kripken Apr 13, 2023
3f3c561
fix
kripken Apr 13, 2023
bf566aa
fix
kripken Apr 14, 2023
9459701
fix
kripken Apr 14, 2023
8dbb1ae
more test workarounds
kripken Apr 14, 2023
b107f47
Merge remote-tracking branch 'origin/main' into safari.bigint
kripken Apr 14, 2023
6b71f83
Merge remote-tracking branch 'origin/main' into safari.bigint
kripken Apr 17, 2023
6973fea
Merge remote-tracking branch 'origin/main' into safari.bigint
kripken Apr 17, 2023
560120a
fix
kripken Apr 17, 2023
84836b2
fix
kripken Apr 17, 2023
356a840
Explain safari-bigint issue and set version to 15
kripken Apr 17, 2023
00aab91
Merge remote-tracking branch 'origin/main' into safari.bigint
kripken Jun 21, 2023
0ca6930
Merge remote-tracking branch 'origin/main' into safari.bigint
kripken Jun 21, 2023
5985cdd
fix
kripken Jun 21, 2023
8566684
fix
kripken Jun 21, 2023
c35d241
Merge remote-tracking branch 'origin/main' into safari.bigint
kripken Jun 22, 2023
b537cc7
fix
kripken Jun 22, 2023
339b323
fix
kripken Jun 22, 2023
400f01e
fix
kripken Jun 22, 2023
62366ca
clean
kripken Jun 22, 2023
2f8f82c
waka
kripken Jun 22, 2023
8eab1f5
fix
kripken Jun 22, 2023
c93f72f
comment
kripken Jun 22, 2023
568ee40
fix
kripken Jun 22, 2023
fe12dc0
flip
kripken Jun 22, 2023
a42cb9e
remove =1s
kripken Jun 22, 2023
4998ef6
merge [ci skip]
kripken Jun 22, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -592,7 +592,7 @@ jobs:
other.test_min_node_version
other.test_node_emscripten_num_logical_cores
core2.test_pthread_create
core2.test_i64_invoke_bigint
core2.test_i64_invoke
core2.test_sse2
core2.test_source_map
core2.test_exceptions_wasm
Expand Down
5 changes: 5 additions & 0 deletions emcc.py
Original file line number Diff line number Diff line change
Expand Up @@ -1896,6 +1896,11 @@ def phase_linker_setup(options, state, newargs):
if settings.LZ4:
settings.EXPORTED_RUNTIME_METHODS += ['LZ4']

# WASM_BIGINT defaults to 1 when VMs support it, and when not using wasm2js
default_setting('WASM_BIGINT',
feature_matrix.caniuse(feature_matrix.Feature.JS_BIGINT_INTEGRATION) and
not settings.WASM2JS)

if settings.PURE_WASI:
settings.STANDALONE_WASM = 1
settings.WASM_BIGINT = 1
Expand Down
6 changes: 6 additions & 0 deletions src/polyfill/bigint64array.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ if (typeof globalThis.BigInt64Array === "undefined") {
}

function createBigIntArrayShim(partsToBigInt) {
/**
* Closure thinks .set is not defined on Proxy objects for some reason. The
* error is on the line with proxy.set but we can only apply the
* suppression at the function level here.
* @suppress {missingProperties}
*/
function createBigInt64Array(array) {
if (typeof array === "number") {
array = new Uint32Array(2 * array);
Expand Down
8 changes: 4 additions & 4 deletions src/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -1382,7 +1382,7 @@ var DYNCALLS = false;
// i64 is used. If WASM_BIGINT is present, the default minimum supported browser
// versions will be increased to the min version that supports BigInt.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This last sentence should probably just be removed I think

// [link]
var WASM_BIGINT = false;
var WASM_BIGINT = true;

// WebAssembly defines a "producers section" which compilers and tools can
// annotate themselves in, and LLVM emits this by default.
Expand Down Expand Up @@ -1745,10 +1745,10 @@ var AUTO_NATIVE_LIBRARIES = true;
// versions >= MIN_FIREFOX_VERSION
// are desired to work. Pass -sMIN_FIREFOX_VERSION=majorVersion to drop support
// for Firefox versions older than < majorVersion.
// Firefox ESR 60.5 (Firefox 65) was released on 2019-01-29.
// Firefox ESR 68 was released on July 9, 2019.
// MAX_INT (0x7FFFFFFF, or -1) specifies that target is not supported.
// [link]
var MIN_FIREFOX_VERSION = 65;
var MIN_FIREFOX_VERSION = 68;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should add this to the ChangeLog, along with a note about bigint itself being enabled by default.


// Specifies the oldest version of desktop Safari to target. Version is encoded
// in MMmmVV, e.g. 70101 denotes Safari 7.1.1.
Expand Down Expand Up @@ -1796,7 +1796,7 @@ var MIN_CHROME_VERSION = 75;
// distinct from the minimum version required run the emscripten compiler.
// This version aligns with the current Ubuuntu TLS 20.04 (Focal).
// Version is encoded in MMmmVV, e.g. 1814101 denotes Node 18.14.01.
var MIN_NODE_VERSION = 101900;
var MIN_NODE_VERSION = 150000;

// Tracks whether we are building with errno support enabled. Set to 0
// to disable compiling errno support in altogether. This saves a little
Expand Down
17 changes: 9 additions & 8 deletions test/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -283,14 +283,13 @@ def metafunc(self, with_bigint):
self.skipTest('wasm2js does not support WASM_BIGINT')
if self.get_setting('WASM_BIGINT') is not None:
self.skipTest('redundant in bigint test config')
self.set_setting('WASM_BIGINT')
self.node_args += shared.node_bigint_flags()
f(self)
else:
self.set_setting('WASM_BIGINT', '0')
f(self)

metafunc._parameterize = {'': (False,),
'bigint': (True,)}
metafunc._parameterize = {'no_bigint': (False,),
'': (True,)}
return metafunc


Expand Down Expand Up @@ -601,10 +600,12 @@ def setUp(self):
else:
# Include backtrace for all uncuaght exceptions (not just Error).
self.node_args.append('--trace-uncaught')
if node_version < (15, 0, 0):
# Opt in to node v15 default behaviour:
# https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode
self.node_args.append('--unhandled-rejections=throw')
if node_version < (15, 0, 0):
# Opt in to node v15 default behaviour:
# https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode
self.node_args.append('--unhandled-rejections=throw')
# WASM_BIGINT requires node 15+
self.emcc_args.append('-sWASM_BIGINT=0')

self.v8_args = ['--wasm-staging']
self.env = {}
Expand Down
1 change: 0 additions & 1 deletion test/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,6 @@
'wasmfs',
'wasm64',
'wasm64l',
'bigint',
]


Expand Down
5 changes: 1 addition & 4 deletions test/test_browser.py
Original file line number Diff line number Diff line change
Expand Up @@ -4017,7 +4017,7 @@ def test_pthread_iostream(self):

@requires_threads
def test_pthread_unistd_io_bigint(self):
self.btest_exit(test_file('unistd/io.c'), args=['-pthread', '-sPROXY_TO_PTHREAD', '-sWASM_BIGINT'])
self.btest_exit(test_file('unistd/io.c'), args=['-pthread', '-sPROXY_TO_PTHREAD'])

# Test that the main thread is able to use pthread_set/getspecific.
@also_with_wasm2js
Expand Down Expand Up @@ -5380,9 +5380,6 @@ def test_dlmalloc_3GB(self):
'main_thread': (['-sPTHREAD_POOL_SIZE=5'],),
# using proxy_to_pthread also works, of course
'proxy_to_pthread': (['-sPROXY_TO_PTHREAD', '-sINITIAL_MEMORY=32MB', '-DPROXYING'],),
# using BigInt support affects the ABI, and should not break things. (this
# could be tested on either thread; do the main thread for simplicity)
'bigint': (['-sPTHREAD_POOL_SIZE=5', '-sWASM_BIGINT'],),
})
@requires_threads
def test_wasmfs_fetch_backend(self, args):
Expand Down
33 changes: 4 additions & 29 deletions test/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,16 +205,10 @@ def metafunc(self, standalone):
if not can_do_standalone(self):
self.skipTest('Test configuration is not compatible with STANDALONE_WASM')
self.set_setting('STANDALONE_WASM')
# we will not legalize the JS ffi interface, so we must use BigInt
# support in order for JS to have a chance to run this without trapping
# when it sees an i64 on the ffi.
self.set_setting('WASM_BIGINT')
self.emcc_args.append('-Wno-unused-command-line-argument')
# if we are impure, disallow all wasm engines
if impure:
self.wasm_engines = []
self.js_engines = [config.NODE_JS]
self.node_args += shared.node_bigint_flags()
func(self)
if wasm2c:
print('wasm2c')
Expand Down Expand Up @@ -545,9 +539,7 @@ def test_i64_varargs(self):
@no_wasm64('MEMORY64 does not yet support exceptions')
@requires_node
def test_i64_invoke_bigint(self):
self.set_setting('WASM_BIGINT')
self.emcc_args += ['-fexceptions']
self.node_args += shared.node_bigint_flags()
self.do_core_test('test_i64_invoke_bigint.cpp')

def test_vararg_copy(self):
Expand Down Expand Up @@ -2327,11 +2319,9 @@ def test_em_js(self, args, force_c):

@no_wasm2js('WASM_BIGINT is not compatible with wasm2js')
def test_em_js_i64(self):
err = self.expect_fail([EMCC, '-Werror', test_file('core/test_em_js_i64.c')])
err = self.expect_fail([EMCC, '-sWASM=0', '-Werror', test_file('core/test_em_js_i64.c')])
self.assertContained('emcc: error: using 64-bit arguments in EM_JS function without WASM_BIGINT is not yet fully supported: `foo`', err)

self.set_setting('WASM_BIGINT')
self.node_args += shared.node_bigint_flags()
self.do_core_test('test_em_js_i64.c')

def test_em_js_address_taken(self):
Expand Down Expand Up @@ -4263,7 +4253,6 @@ def test_dylink_basics_no_modify(self):
self.skipTest('no modify mode only works with non-optimizing builds')
if self.get_setting('MEMORY64') == 2:
self.skipTest('MEMORY64=2 always requires module re-writing')
self.set_setting('WASM_BIGINT')
self.set_setting('ERROR_ON_WASM_CHANGES_AFTER_LINK')
self.do_basic_dylink_test()

Expand Down Expand Up @@ -7143,12 +7132,6 @@ def test_autodebug_wasm(self):
'none': ('none',),
})
def test_wasm2c_sandboxing(self, mode):
if self.get_setting('WASMFS'):
# wasm2c disables JS legalization since we are building in standalone
# mode. this happens to work without wasmfs, but with wasmfs we get the
# time when we create/update a file, which uses clock_time_get that has an
# i64 param. For such an import to work we need wasm-bigint support.
self.node_args += shared.node_bigint_flags()
if not can_do_standalone(self):
return self.skipTest('standalone mode not supported')
self.set_setting('STANDALONE_WASM')
Expand Down Expand Up @@ -7231,8 +7214,8 @@ def test_EXPORTED_RUNTIME_METHODS(self):
'minimal_runtime': ['-sMINIMAL_RUNTIME=1']
})
def test_dyncall_specific(self, *args):
if self.get_setting('WASM_BIGINT') or self.get_setting('MEMORY64'):
self.skipTest('not compatible with WASM_BIGINT')
if self.get_setting('MEMORY64'):
self.skipTest('not compatible with MEMORY64')
cases = [
('DIRECT', []),
('DYNAMIC_SIG', ['-sDYNCALLS=1']),
Expand Down Expand Up @@ -7721,16 +7704,12 @@ def test_embind_dynamic_initialization(self):

@no_wasm2js('wasm_bigint')
def test_embind_i64_val(self):
self.set_setting('WASM_BIGINT')
self.emcc_args += ['-lembind']
self.node_args += shared.node_bigint_flags()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are there any remaining callers of node_bigint_flags?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one is not needed, but there are still two uses after it, in emcc.py and gen_struct_info.py which I am not sure about.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To remove it in them, we might need to add node version checks...

self.do_run_in_out_file_test('embind/test_i64_val.cpp', assert_identical=True)

@no_wasm2js('wasm_bigint')
def test_embind_i64_binding(self):
self.set_setting('WASM_BIGINT')
self.emcc_args += ['-lembind']
self.node_args += shared.node_bigint_flags()
self.do_run_in_out_file_test('embind/test_i64_binding.cpp', assert_identical=True)

def test_embind_no_rtti(self):
Expand Down Expand Up @@ -9844,8 +9823,7 @@ def setUp(self):
settings={'MEMORY64': 1}, require_wasm64=True, require_v8=True)
# MEMORY64=2, or "lowered"
wasm64l = make_run('wasm64l', emcc_args=['-Wno-experimental', '--profiling-funcs'],
settings={'MEMORY64': 2},
node_args=shared.node_bigint_flags())
settings={'MEMORY64': 2})

lto0 = make_run('lto0', emcc_args=['-flto', '-O0'])
lto1 = make_run('lto1', emcc_args=['-flto', '-O1'])
Expand Down Expand Up @@ -9881,9 +9859,6 @@ def setUp(self):
core2s = make_run('core2s', emcc_args=['-O2'], settings={'SAFE_HEAP': 1})
core2ss = make_run('core2ss', emcc_args=['-O2'], settings={'STACK_OVERFLOW_CHECK': 2})

bigint = make_run('bigint', emcc_args=['--profiling-funcs'], settings={'WASM_BIGINT': 1},
node_args=shared.node_bigint_flags())

# Add DEFAULT_TO_CXX=0
strict = make_run('strict', emcc_args=[], settings={'STRICT': 1})

Expand Down
58 changes: 21 additions & 37 deletions test/test_other.py
Original file line number Diff line number Diff line change
Expand Up @@ -1986,14 +1986,12 @@ def test_dylink_pthread_warning(self):
@node_pthreads
def test_dylink_pthread_bigint_em_asm(self):
self.set_setting('MAIN_MODULE', 2)
self.set_setting('WASM_BIGINT')
self.emcc_args += ['-Wno-experimental', '-pthread']
self.do_runf(test_file('hello_world_em_asm.c'), 'hello, world')

@node_pthreads
def test_dylink_pthread_bigint_em_js(self):
self.set_setting('MAIN_MODULE', 2)
self.set_setting('WASM_BIGINT')
self.emcc_args += ['-Wno-experimental', '-pthread']
self.do_runf(test_file('core/test_em_js.cpp'))

Expand Down Expand Up @@ -4477,20 +4475,14 @@ def guess_symbols_file_type(symbols_file):
self.assertContained(UNMINIFIED_HEAP8, js)
self.assertContained(UNMINIFIED_MIDDLE, js)

@parameterized({
'': [[]],
# bigint support is interesting to test here because it changes which
# binaryen tools get run, which can affect how debug info is kept around
'bigint': [['-sWASM_BIGINT']],
})
def test_symbol_map_output_size(self, args):
def test_symbol_map_output_size(self):
# build with and without a symbol map and verify that the sizes are the
# same. using a symbol map should add the map on the side, but not increase
# the build size.
# -Oz is used here to run as many optimizations as possible, to check for
# any difference in how the optimizer operates
self.run_process([EMCC, test_file('hello_world.c'), '-Oz', '-o', 'test1.js'] + args)
self.run_process([EMCC, test_file('hello_world.c'), '-Oz', '-o', 'test2.js', '--emit-symbol-map'] + args)
self.run_process([EMCC, test_file('hello_world.c'), '-Oz', '-o', 'test1.js'])
self.run_process([EMCC, test_file('hello_world.c'), '-Oz', '-o', 'test2.js', '--emit-symbol-map'])
self.assertEqual(os.path.getsize('test1.js'), os.path.getsize('test2.js'))
self.assertEqual(os.path.getsize('test1.wasm'), os.path.getsize('test2.wasm'))

Expand Down Expand Up @@ -7332,14 +7324,8 @@ def test_memory_growth_noasm(self):
assert 'use asm' not in src

def test_EM_ASM_i64(self):
expected = 'Invalid character 106("j") in readEmAsmArgs!'
self.do_runf(test_file('other/test_em_asm_i64.cpp'),
expected_output=expected,
assert_returncode=NON_ZERO)

self.set_setting('WASM_BIGINT')
self.do_other_test('test_em_asm_i64.cpp')
self.do_other_test('test_em_asm_i64.cpp', force_c=True)
# self.do_other_test('test_em_asm_i64.cpp', force_c=True)

def test_eval_ctor_ordering(self):
# ensure order of execution remains correct, even with a bad ctor
Expand Down Expand Up @@ -11091,19 +11077,18 @@ def ok(args, filename='hello_world.cpp', expected='hello, world!'):
args += ['-sERROR_ON_WASM_CHANGES_AFTER_LINK']
self.do_runf(test_file(filename), expected, emcc_args=args)

# -O0 with BigInt support (to avoid the need for legalization)
required_flags = ['-sWASM_BIGINT']
ok(required_flags)
# -O0 just works
ok([])
# Same with DWARF
ok(required_flags + ['-g'])
ok(['-g'])
# Function pointer calls from JS work too
ok(required_flags, filename='hello_world_main_loop.cpp')
ok([], filename='hello_world_main_loop.cpp')
# -O1 is ok as we don't run wasm-opt there (but no higher, see below)
ok(required_flags + ['-O1'])
ok(['-O1'])
# Exception support shouldn't require changes after linking
ok(required_flags + ['-fexceptions'])
ok(['-fexceptions'])
# Standalone mode should not do anything special to the wasm.
ok(required_flags + ['-sSTANDALONE_WASM'])
ok(['-sSTANDALONE_WASM'])

# other builds fail with a standard message + extra details
def fail(args, details):
Expand All @@ -11113,13 +11098,10 @@ def fail(args, details):
self.assertContained('changes to the wasm are required after link, but disallowed by ERROR_ON_WASM_CHANGES_AFTER_LINK', err)
self.assertContained(details, err)

# plain -O0
legalization_message = 'to disable int64 legalization (which requires changes after link) use -sWASM_BIGINT'
fail([], legalization_message)
# optimized builds even without legalization
optimization_message = '-O2+ optimizations always require changes, build with -O0 or -O1 instead'
fail(required_flags + ['-O2'], optimization_message)
fail(required_flags + ['-O3'], optimization_message)
fail(['-O2'], optimization_message)
fail(['-O3'], optimization_message)

@crossplatform
def test_output_to_nowhere(self):
Expand Down Expand Up @@ -11489,7 +11471,6 @@ def test_standalone_export_main(self):
@requires_wasm_eh
def test_standalone_wasm_exceptions(self):
self.set_setting('STANDALONE_WASM')
self.set_setting('WASM_BIGINT')
self.wasm_engines = []
self.emcc_args += ['-fwasm-exceptions']
self.do_run_from_file(test_file('core/test_exceptions.cpp'), test_file('core/test_exceptions_caught.out'))
Expand Down Expand Up @@ -11705,7 +11686,7 @@ def test_this_in_dyncall_memory64(self):
@parameterized({
'plain': [[]],
'asyncify': [['-sASYNCIFY']],
'asyncify_bigint': [['-sASYNCIFY', '-sWASM_BIGINT']]})
})
def test_closure_safe(self, args):
self.run_process([EMCC, test_file('hello_world.c'), '--closure=1'] + args)

Expand Down Expand Up @@ -12617,8 +12598,6 @@ def test_wasmfs_readfile(self):
@wasmfs_all_backends
def test_wasmfs_readfile_bigint(self):
self.set_setting('FORCE_FILESYSTEM')
self.set_setting('WASM_BIGINT')
self.node_args += shared.node_bigint_flags()
self.do_run_in_out_file_test(test_file('wasmfs/wasmfs_readfile.c'))

def test_wasmfs_jsfile(self):
Expand Down Expand Up @@ -13180,7 +13159,7 @@ def test_reproduce(self):

def test_min_browser_version(self):
err = self.expect_fail([EMCC, test_file('hello_world.c'), '-Werror', '-sWASM_BIGINT', '-sMIN_SAFARI_VERSION=120000'])
self.assertContained('emcc: error: MIN_SAFARI_VERSION=120000 is not compatible with WASM_BIGINT (150000 or above required)', err)
self.assertContained('emcc: error: MIN_SAFARI_VERSION=120000 is not compatible with WASM_BIGINT (140100 or above required)', err)

err = self.expect_fail([EMCC, test_file('hello_world.c'), '-Werror', '-pthread', '-sMIN_CHROME_VERSION=73'])
self.assertContained('emcc: error: MIN_CHROME_VERSION=73 is not compatible with pthreads (74 or above required)', err)
Expand Down Expand Up @@ -13285,6 +13264,12 @@ def test_min_node_version(self):
expected = 'This emscripten-generated code requires node v21.0.0 (detected v%s' % node_version
self.do_runf(test_file('hello_world.c'), expected, assert_returncode=NON_ZERO)

def test_min_node_version_bigint(self):
err = self.expect_fail([EMCC, test_file('hello_world.c'), '-Werror', '-sWASM_BIGINT', '-sMIN_NODE_VERSION=149999'])
self.assertContained('emcc: error: MIN_NODE_VERSION=149999 is not compatible with WASM_BIGINT (150000 or above required)', err)

self.run_process([EMCC, test_file('hello_world.c'), '-Werror', '-sWASM_BIGINT', '-sMIN_NODE_VERSION=150000'])

def test_deprecated_macros(self):
create_file('main.c', '''
#include <assert.h>
Expand Down Expand Up @@ -13337,7 +13322,6 @@ def test_missing_struct_info(self):
def run_wasi_test_suite_test(self, name):
if not os.path.exists(path_from_root('test/third_party/wasi-test-suite')):
self.fail('wasi-testsuite not found; run `git submodule update --init`')
self.node_args += shared.node_bigint_flags()
wasm = path_from_root('test', 'third_party', 'wasi-test-suite', name + '.wasm')
with open(path_from_root('test', 'third_party', 'wasi-test-suite', name + '.json')) as f:
config = json.load(f)
Expand Down
Loading