Skip to content

Commit

Permalink
Move reSign/unSign to library function. NFC. (#12014)
Browse files Browse the repository at this point in the history
These were only used by library_formatString.js
  • Loading branch information
sbc100 committed Aug 24, 2020
1 parent 2309954 commit 8b5e1bc
Show file tree
Hide file tree
Showing 7 changed files with 52 additions and 58 deletions.
2 changes: 1 addition & 1 deletion emcc.py
Original file line number Diff line number Diff line change
Expand Up @@ -1505,7 +1505,7 @@ def check(input_file):

if shared.Settings.SAFE_HEAP:
# SAFE_HEAP check includes calling emscripten_get_sbrk_ptr().
shared.Settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE += ['emscripten_get_sbrk_ptr']
shared.Settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE += ['emscripten_get_sbrk_ptr', '$unSign']

if not shared.Settings.DECLARE_ASM_MODULE_EXPORTS:
shared.Settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE += ['$exportAsmFunctions']
Expand Down
35 changes: 34 additions & 1 deletion src/library_formatString.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,44 @@ mergeInto(LibraryManager.library, {
return x < 0 || (x === 0 && (1/x) === -Infinity);
},

// Converts a value we have as signed, into an unsigned value. For
// example, -1 in int32 would be a very large number as unsigned.
$unSign: function(value, bits) {
if (value >= 0) {
return value;
}
// Need some trickery, since if bits == 32, we are right at the limit of the
// bits JS uses in bitshifts
return bits <= 32 ? 2*Math.abs(1 << (bits-1)) + value
: Math.pow(2, bits) + value;
},

// Converts a value we have as unsigned, into a signed value. For
// example, 200 in a uint8 would be a negative number.
$reSign: function(value, bits) {
if (value <= 0) {
return value;
}
var half = bits <= 32 ? Math.abs(1 << (bits-1)) // abs is needed if bits == 32
: Math.pow(2, bits-1);
// for huge values, we can hit the precision limit and always get true here.
// so don't do that but, in general there is no perfect solution here. With
// 64-bit ints, we get rounding and errors
// TODO: In i64 mode 1, resign the two parts separately and safely
if (value >= half && (bits <= 32 || value > half)) {
// Cannot bitshift half, as it may be at the limit of the bits JS uses in
// bitshifts
value = -2*half + value;
}
return value;
},

// Performs printf-style formatting.
// format: A pointer to the format string.
// varargs: A pointer to the start of the arguments list.
// Returns the resulting string string as a character array.
$formatString__deps: ['$reallyNegative', '$convertI32PairToI53', '$convertU32PairToI53'
$formatString__deps: ['$reallyNegative', '$convertI32PairToI53', '$convertU32PairToI53',
'$reSign', '$unSign'
#if MINIMAL_RUNTIME
, '$intArrayFromString'
#endif
Expand Down
5 changes: 0 additions & 5 deletions src/preamble.js
Original file line number Diff line number Diff line change
Expand Up @@ -550,11 +550,6 @@ function addOnPostRun(cb) {
__ATPOSTRUN__.unshift(cb);
}
/** @param {number|boolean=} ignore */
{{{ unSign }}}
/** @param {number|boolean=} ignore */
{{{ reSign }}}
#include "runtime_math.js"
// A counter of dependencies for calling run(). If we need to
Expand Down
5 changes: 0 additions & 5 deletions src/preamble_minimal.js
Original file line number Diff line number Diff line change
Expand Up @@ -232,11 +232,6 @@ var runtimeInitialized = false;
var runtimeExited = false;
#endif
/** @param {number|boolean=} ignore */
{{{ unSign }}}
/** @param {number|boolean=} ignore */
{{{ reSign }}}
#include "runtime_math.js"
var memoryInitializer = null;
Expand Down
26 changes: 0 additions & 26 deletions src/runtime.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,32 +64,6 @@ var Runtime = {

// Additional runtime elements, that need preprocessing

// Converts a value we have as signed, into an unsigned value. For
// example, -1 in int32 would be a very large number as unsigned.
function unSign(value, bits, ignore) {
if (value >= 0) {
return value;
}
return bits <= 32 ? 2*Math.abs(1 << (bits-1)) + value // Need some trickery, since if bits == 32, we are right at the limit of the bits JS uses in bitshifts
: Math.pow(2, bits) + value;
}

// Converts a value we have as unsigned, into a signed value. For
// example, 200 in a uint8 would be a negative number.
function reSign(value, bits, ignore) {
if (value <= 0) {
return value;
}
var half = bits <= 32 ? Math.abs(1 << (bits-1)) // abs is needed if bits == 32
: Math.pow(2, bits-1);
if (value >= half && (bits <= 32 || value > half)) { // for huge values, we can hit the precision limit and always get true here. so don't do that
// but, in general there is no perfect solution here. With 64-bit ints, we get rounding and errors
// TODO: In i64 mode 1, resign the two parts separately and safely
value = -2*half + value; // Cannot bitshift half, as it may be at the limit of the bits JS uses in bitshifts
}
return value;
}

// Allocated here in JS, after we have the runtime etc. prepared.
// This constant is emitted into the JS or wasm code.
var DYNAMICTOP_PTR = makeStaticAlloc(4);
Expand Down
2 changes: 1 addition & 1 deletion src/runtime_safe_heap.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ function SAFE_HEAP_LOAD(dest, bytes, unsigned, isFloat) {
assert(HEAP32[DYNAMICTOP_PTR>>2] <= HEAP8.length);
var type = getSafeHeapType(bytes, isFloat);
var ret = getValue(dest, type, 1);
if (unsigned) ret = unSign(ret, parseInt(type.substr(1), 10), 1);
if (unsigned) ret = unSign(ret, parseInt(type.substr(1), 10));
#if SAFE_HEAP_LOG
out('SAFE_HEAP load: ' + [dest, ret, bytes, isFloat, unsigned, SAFE_HEAP_COUNTER++]);
#endif
Expand Down
35 changes: 16 additions & 19 deletions tests/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -6142,27 +6142,24 @@ def test_bullet(self, use_cmake):
@needs_make('depends on freetype')
@is_slow_test
def test_poppler(self):
def test():
pdf_data = open(path_from_root('tests', 'poppler', 'paper.pdf'), 'rb').read()
create_test_file('paper.pdf.js', str(list(bytearray(pdf_data))))

create_test_file('pre.js', '''
Module.preRun = function() {
FS.createDataFile('/', 'paper.pdf', eval(read_('paper.pdf.js')), true, false, false);
};
Module.postRun = function() {
var FileData = MEMFS.getFileDataAsRegularArray(FS.root.contents['filename-1.ppm']);
out("Data: " + JSON.stringify(FileData.map(function(x) { return unSign(x, 8) })));
};
''')
self.emcc_args += ['--pre-js', 'pre.js']
pdf_data = open(path_from_root('tests', 'poppler', 'paper.pdf'), 'rb').read()
create_test_file('paper.pdf.js', str(list(bytearray(pdf_data))))

ppm_data = str(list(bytearray(open(path_from_root('tests', 'poppler', 'ref.ppm'), 'rb').read())))
self.do_run('', ppm_data.replace(' ', ''),
libraries=self.get_poppler_library(),
args=['-scale-to', '512', 'paper.pdf', 'filename'])
create_test_file('pre.js', '''
Module.preRun = function() {
FS.createDataFile('/', 'paper.pdf', eval(read_('paper.pdf.js')), true, false, false);
};
Module.postRun = function() {
var FileData = MEMFS.getFileDataAsRegularArray(FS.root.contents['filename-1.ppm']);
out("Data: " + JSON.stringify(FileData.map(function(x) { return unSign(x, 8) })));
};
''')
self.emcc_args += ['--pre-js', 'pre.js', '-s', 'DEFAULT_LIBRARY_FUNCS_TO_INCLUDE=[$unSign]']

test()
ppm_data = str(list(bytearray(open(path_from_root('tests', 'poppler', 'ref.ppm'), 'rb').read())))
self.do_run('', ppm_data.replace(' ', ''),
libraries=self.get_poppler_library(),
args=['-scale-to', '512', 'paper.pdf', 'filename'])

@needs_make('make')
@is_slow_test
Expand Down

0 comments on commit 8b5e1bc

Please sign in to comment.