Skip to content

Commit 9a96344

Browse files
committed
fix merge conflict (emscripten-core#5296)
2 parents 7830cc1 + 04eae7b commit 9a96344

35 files changed

+351
-102
lines changed

AUTHORS

+1
Original file line numberDiff line numberDiff line change
@@ -296,3 +296,4 @@ a license to everyone to use it as detailed in LICENSE.)
296296
* Yair Levinson (copyright owned by Autodesk, Inc.)
297297
* Matjaž Drolc <[email protected]>
298298
* James Swift <[email protected]> (copyright owned by PSPDFKit GmbH)
299+
* Sam Clegg <[email protected]> (copyright owned by Google, Inc.

emcc.py

+11-13
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@
9494
final = None
9595

9696

97-
class Intermediate:
97+
class Intermediate(object):
9898
counter = 0
9999
def save_intermediate(name=None, suffix='js'):
100100
name = os.path.join(shared.get_emscripten_temp_dir(), 'emcc-%d%s.%s' % (Intermediate.counter, '' if name is None else '-' + name, suffix))
@@ -105,7 +105,7 @@ def save_intermediate(name=None, suffix='js'):
105105
Intermediate.counter += 1
106106

107107

108-
class TimeLogger:
108+
class TimeLogger(object):
109109
last = time.time()
110110

111111
@staticmethod
@@ -120,7 +120,7 @@ def log_time(name):
120120
TimeLogger.update()
121121

122122

123-
class EmccOptions:
123+
class EmccOptions(object):
124124
def __init__(self):
125125
self.opt_level = 0
126126
self.debug_level = 0
@@ -166,7 +166,7 @@ def __init__(self):
166166
self.output_eol = os.linesep
167167

168168

169-
class JSOptimizer:
169+
class JSOptimizer(object):
170170
def __init__(self, target, options, misc_temp_files, js_transform_tempfiles):
171171
self.queue = []
172172
self.extra_info = {}
@@ -373,11 +373,10 @@ def run():
373373
input_file = 'hello_world.c'
374374
out, err = subprocess.Popen([shared.PYTHON] + args + [shared.path_from_root('tests', input_file), '-c', '-o', temp_target], stderr=subprocess.PIPE, env=debug_env).communicate()
375375
lines = filter(lambda x: shared.CLANG_CC in x and input_file in x, err.split(os.linesep))
376-
line = lines[0]
377-
assert 'running:' in line
378-
parts = line.split(' ')[2:]
376+
line = re.search('running: (.*)', lines[0]).group(1)
377+
parts = shlex.split(line)
379378
parts = filter(lambda x: x != '-c' and x != '-o' and input_file not in x and temp_target not in x and '-emit-llvm' not in x, parts)
380-
print ' '.join(parts)
379+
print ' '.join(shared.Building.doublequote_spaces(parts))
381380
exit(0)
382381

383382
def is_minus_s_for_emcc(newargs, i):
@@ -826,7 +825,7 @@ def get_last_setting_change(setting):
826825

827826
# If not compiling to JS, then we are compiling to an intermediate bitcode objects or library, so
828827
# ignore dynamic linking, since multiple dynamic linkings can interfere with each other
829-
if not filename_type_suffix(target) in JS_CONTAINING_SUFFIXES or options.ignore_dynamic_linking:
828+
if filename_type_suffix(target) not in JS_CONTAINING_SUFFIXES or options.ignore_dynamic_linking:
830829
def check(input_file):
831830
if filename_type_ending(input_file) in DYNAMICLIB_ENDINGS:
832831
if not options.ignore_dynamic_linking: logging.warning('ignoring dynamic library %s because not compiling to JS or HTML, remember to link it when compiling to JS or HTML at the end', os.path.basename(input_file))
@@ -1291,7 +1290,7 @@ def compile_source_file(i, input_file):
12911290
output_file = get_bitcode_file(input_file)
12921291
temp_files.append((i, output_file))
12931292
args = get_bitcode_args([input_file]) + ['-emit-llvm', '-c', '-o', output_file]
1294-
logging.debug("running: " + ' '.join(args))
1293+
logging.debug("running: " + ' '.join(shared.Building.doublequote_spaces(args))) # NOTE: Printing this line here in this specific format is important, it is parsed to implement the "emcc --cflags" command
12951294
execute(args) # let compiler frontend print directly, so colors are saved (PIPE kills that)
12961295
if not os.path.exists(output_file):
12971296
logging.error('compiler frontend failed to generate LLVM bitcode, halting')
@@ -1663,7 +1662,6 @@ def repl(m):
16631662
)
16641663
with ToolchainProfiler.profile_block('js opts'):
16651664
# It is useful to run several js optimizer passes together, to save on unneeded unparsing/reparsing
1666-
16671665
if shared.Settings.DEAD_FUNCTIONS:
16681666
optimizer.queue += ['eliminateDeadFuncs']
16691667
optimizer.extra_info['dead_functions'] = shared.Settings.DEAD_FUNCTIONS
@@ -2166,7 +2164,7 @@ def binaryen_method_sanity_check():
21662164
methods = shared.Settings.BINARYEN_METHOD.split(',')
21672165
valid_methods = ['asmjs', 'native-wasm', 'interpret-s-expr', 'interpret-binary', 'interpret-asm2wasm']
21682166
for m in methods:
2169-
if not m.strip() in valid_methods:
2167+
if m.strip() not in valid_methods:
21702168
logging.error('Unrecognized BINARYEN_METHOD "' + m.strip() + '" specified! Please pass a comma-delimited list containing one or more of: ' + ','.join(valid_methods))
21712169
sys.exit(1)
21722170

@@ -2533,7 +2531,7 @@ def system_js_libraries_setting_str(libs, lib_dirs, settings_changes, input_file
25332531
return 'SYSTEM_JS_LIBRARIES="' + ','.join(libraries) + '"'
25342532

25352533

2536-
class ScriptSource:
2534+
class ScriptSource(object):
25372535
def __init__(self):
25382536
self.src = None # if set, we have a script to load with a src attribute
25392537
self.inline = None # if set, we have the contents of a script to write inline in a script

emscripten.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -685,7 +685,7 @@ def unfloat(s):
685685

686686

687687
def make_function_tables_defs(implemented_functions, all_implemented, function_table_data, settings, metadata):
688-
class Counter:
688+
class Counter(object):
689689
next_bad_item = 0
690690
next_item = 0
691691
pre = []
@@ -2076,7 +2076,10 @@ def main(args, compiler_engine, cache, temp_files, DEBUG):
20762076
settings = {}
20772077
for setting in args.settings:
20782078
name, value = setting.strip().split('=', 1)
2079-
settings[name] = json.loads(value)
2079+
value = json.loads(value)
2080+
if isinstance(value, unicode):
2081+
value = value.encode('utf8')
2082+
settings[name] = value
20802083

20812084
# libraries
20822085
libraries = args.libraries[0].split(',') if len(args.libraries) > 0 else []

site/source/docs/porting/multimedia_and_graphics/OpenGL-support.rst

+13-7
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ OpenGL support in Emscripten
66

77
Emscripten provides three OpenGL modes:
88

9-
- :ref:`opengl-support-webgl-subset` (default) — supports the set of OpenGL ES commands that map directly to WebGL.
10-
- :ref:`opengl-support-opengl-es2-0-emulation` — support for some emulated OpenGL ES 2.0 features that are not present in WebGL.
9+
- :ref:`opengl-support-webgl-subset` (default) — supports the set of OpenGL ES 2.0/3.0 commands that map directly to WebGL 1/2.
10+
- :ref:`opengl-support-opengl-es2-0-emulation` — support for some emulated OpenGL ES 2.0/3.0 features that are not present in WebGL.
1111
- :ref:`opengl-support-legacy_and_mobile` — support for a number of legacy GL 1.x features and commands.
1212

1313
This topic provides information about the modes, and how they are enabled.
@@ -16,21 +16,23 @@ This topic provides information about the modes, and how they are enabled.
1616

1717
.. _opengl-support-webgl-subset:
1818

19-
WebGL-friendly subset of OpenGL ES
20-
==================================
19+
WebGL-friendly subset of OpenGL ES 2.0/3.0
20+
==========================================
2121

2222
By default, Emscripten targets the WebGL-friendly subset of OpenGL ES 2.0. This is the set of GL ES commands that map directly to WebGL, so that each GL command has a roughly direct mapping to WebGL. It includes almost all of OpenGL ES 2.0, with the notable exception of client-side arrays, and some other features that are listed in `WebGL 1.0 Specification/Chapter 6 <https://www.khronos.org/registry/webgl/specs/1.0/#6>`_.
2323

2424
To program against the WebGL subset of OpenGL ES, one uses the GL ES 2.0 header files and the GL ES 2.0 API, while adhering to the limitations specified in Chapter 6 of the WebGL specification.
2525

2626
This mode is used by default because it best matches the WebGL features brovided by browsers.
2727

28+
To target WebGL 2, pass the linker flag ``-s USE_WEBGL2=1``. Specifying this flag enables (and defaults to, unless otherwise specified at context creation time) the creation of WebGL 2 contexts at runtime, but it is still possible to create WebGL 1 contexts, so applications can choose whether to require WebGL 2 or whether to support a fallback to WebGL 1.
29+
2830
.. _opengl-support-opengl-es2-0-emulation:
2931

30-
OpenGL ES 2.0 emulation
31-
=======================
32+
OpenGL ES 2.0/3.0 emulation
33+
===========================
3234

33-
This build mode emulates some features of OpenGL ES 2.0 that are not part of the core WebGL 1 specification.
35+
This build mode emulates some features of OpenGL ES 2.0/3.0 that are not part of the core WebGL 1 specification.
3436

3537
In particular, this mode emulates client-side arrays that are missing [#f1]_ from the :ref:`opengl-support-webgl-subset`.
3638

@@ -40,6 +42,8 @@ This allows you to use functions `glDrawArrays <https://www.opengl.org/sdk/docs/
4042

4143
To enable *OpenGL ES 2.0 emulation*, specify the :ref:`emcc <emcc-s-option-value>` option ``-s FULL_ES2=1`` when linking the final executable (.js/.html) of the project.
4244

45+
To enable *OpenGL ES 3.0 emulation*, specify the :ref:`emcc <emcc-s-option-value>` option ``-s FULL_ES3=1`` when linking the final executable (.js/.html) of the project. This adds emulation for mapping memory blocks to client side memory. The flags ``-s FULL_ES2=1`` and ``-s FULL_ES3=1`` are orthogonal, so either one or both can be specified to emulate different features.
46+
4347
.. _opengl-support-legacy_and_mobile:
4448

4549
Emulation of older Desktop OpenGL API features
@@ -72,6 +76,8 @@ When porting code, it should be noted that desktop OpenGL, OpenGL ES and WebGL e
7276

7377
Additionally, in WebGL, unlike in desktop or mobile OpenGL, extensions must be activated first before the features they expose take effect. If you use one of the native APIs SDL, EGL, GLUT or GLFW to create your GL context, this will be done automatically for most extensions. If instead you use the HTML5 WebGL context creation API, you must explicitly choose whether to autoenable WebGL extensions. If an extension was not automatically enabled at context creation time, the HTML5 API function `emscripten_webgl_enable_extension` can be used to activate it. Debugging related extensions, draft extensions and vendor-prefixed extensions (MOZ_*, WEBKIT_*) are never enabled automatically at context creation time, but must always be activated manually.
7478

79+
When migrating from WebGL 1 to WebGL 2, take note that some WebGL 1 extensions are migrated to core WebGL 2, and therefore their functionality is no longer advertised as GL extensions. This does not mean that the features would be missing, but that it is possible to utilize these features in WebGL 2 without needing to feature test the presence of a GL extension first.
80+
7581
Test code/examples
7682
==================
7783

src/embind/embind.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -536,6 +536,8 @@ var LibraryEmbind = {
536536
};
537537
}
538538

539+
var isUnsignedType = (name.indexOf('unsigned') != -1);
540+
539541
registerType(primitiveType, {
540542
name: name,
541543
'fromWireType': fromWireType,
@@ -548,7 +550,7 @@ var LibraryEmbind = {
548550
if (value < minRange || value > maxRange) {
549551
throw new TypeError('Passing a number "' + _embind_repr(value) + '" from JS side to C/C++ side to an argument of type "' + name + '", which is outside the valid range [' + minRange + ', ' + maxRange + ']!');
550552
}
551-
return value | 0;
553+
return isUnsignedType ? (value >>> 0) : (value | 0);
552554
},
553555
'argPackAdvance': 8,
554556
'readValueFromPointer': integerReadValueFromPointer(name, shift, minRange !== 0),

src/library.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -496,8 +496,8 @@ LibraryManager.library = {
496496
totalMemory = getTotalMemory()|0;
497497
if ((newDynamicTop|0) > (totalMemory|0)) {
498498
if ((enlargeMemory()|0) == 0) {
499-
___setErrNo({{{ cDefine('ENOMEM') }}});
500499
HEAP32[DYNAMICTOP_PTR>>2] = oldDynamicTop;
500+
___setErrNo({{{ cDefine('ENOMEM') }}});
501501
return -1;
502502
}
503503
}

src/library_glfw.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1086,7 +1086,7 @@ var LibraryGLFW = {
10861086
},
10871087

10881088
glfwSetTime: function(time) {
1089-
GLFW.initialTime = GLFW.getTime() + time;
1089+
GLFW.initialTime = GLFW.getTime() - time;
10901090
},
10911091

10921092
glfwExtensionSupported: function(extension) {

src/library_sdl.js

+6-3
Original file line numberDiff line numberDiff line change
@@ -3001,14 +3001,17 @@ var LibrarySDL = {
30013001
var w = SDL.estimateTextWidth(fontData, text);
30023002
var h = fontData.size;
30033003
var color = SDL.loadColorToCSSRGB(color); // XXX alpha breaks fonts?
3004-
var fontString = h + 'px ' + fontData.name;
3004+
var fontString = h + 'px ' + fontData.name + ', serif';
30053005
var surf = SDL.makeSurface(w, h, 0, false, 'text:' + text); // bogus numbers..
30063006
var surfData = SDL.surfaces[surf];
30073007
surfData.ctx.save();
30083008
surfData.ctx.fillStyle = color;
30093009
surfData.ctx.font = fontString;
3010-
surfData.ctx.textBaseline = 'top';
3011-
surfData.ctx.fillText(text, 0, 0);
3010+
// use bottom alligment, because it works
3011+
// same in all browsers, more info here:
3012+
// https://bugzilla.mozilla.org/show_bug.cgi?id=737852
3013+
surfData.ctx.textBaseline = 'bottom';
3014+
surfData.ctx.fillText(text, 0, h|0);
30123015
surfData.ctx.restore();
30133016
return surf;
30143017
},

src/preamble.js

+23-3
Original file line numberDiff line numberDiff line change
@@ -1111,6 +1111,8 @@ function enlargeMemory() {
11111111
Module.printErr('Expected to get back a buffer of size ' + TOTAL_MEMORY + ' bytes, but instead got back a buffer of size ' + replacement.byteLength);
11121112
}
11131113
#endif
1114+
// restore the state to before this call, we failed
1115+
TOTAL_MEMORY = OLD_TOTAL_MEMORY;
11141116
return false;
11151117
}
11161118

@@ -1981,7 +1983,7 @@ addOnPreRun(function() {
19811983
addRunDependency('preload_dynamicLibraries');
19821984
var binaries = [];
19831985
Module['dynamicLibraries'].forEach(function(lib) {
1984-
fetch(lib).then(function(response) {
1986+
fetch(lib, { credentials: 'same-origin' }).then(function(response) {
19851987
if (!response['ok']) {
19861988
throw "failed to load wasm binary file at '" + lib + "'";
19871989
}
@@ -2229,7 +2231,7 @@ function integrateWasmJS(Module) {
22292231
function getBinaryPromise() {
22302232
// if we don't have the binary yet, and have the Fetch api, use that
22312233
if (!Module['wasmBinary'] && typeof fetch === 'function') {
2232-
return fetch(wasmBinaryFile).then(function(response) {
2234+
return fetch(wasmBinaryFile, { credentials: 'same-origin' }).then(function(response) {
22332235
if (!response['ok']) {
22342236
throw "failed to load wasm binary file at '" + wasmBinaryFile + "'";
22352237
}
@@ -2404,12 +2406,16 @@ function integrateWasmJS(Module) {
24042406
Module['asmPreload'] = Module['asm'];
24052407

24062408
// Memory growth integration code
2407-
Module['reallocBuffer'] = function(size) {
2409+
2410+
var asmjsReallocBuffer = Module['reallocBuffer'];
2411+
2412+
var wasmReallocBuffer = function(size) {
24082413
var PAGE_MULTIPLE = Module["usingWasm"] ? WASM_PAGE_SIZE : ASMJS_PAGE_SIZE; // In wasm, heap size must be a multiple of 64KB. In asm.js, they need to be multiples of 16MB.
24092414
size = alignUp(size, PAGE_MULTIPLE); // round up to wasm page size
24102415
var old = Module['buffer'];
24112416
var oldSize = old.byteLength;
24122417
if (Module["usingWasm"]) {
2418+
// native wasm support
24132419
try {
24142420
var result = Module['wasmMemory'].grow((size - oldSize) / wasmPageSize); // .grow() takes a delta compared to the previous size
24152421
if (result !== (-1 | 0)) {
@@ -2425,12 +2431,24 @@ function integrateWasmJS(Module) {
24252431
return null;
24262432
}
24272433
} else {
2434+
// wasm interpreter support
24282435
exports['__growWasmMemory']((size - oldSize) / wasmPageSize); // tiny wasm method that just does grow_memory
24292436
// in interpreter, we replace Module.buffer if we allocate
24302437
return Module['buffer'] !== old ? Module['buffer'] : null; // if it was reallocated, it changed
24312438
}
24322439
};
24332440

2441+
Module['reallocBuffer'] = function(size) {
2442+
if (finalMethod === 'asmjs') {
2443+
return asmjsReallocBuffer(size);
2444+
} else {
2445+
return wasmReallocBuffer(size);
2446+
}
2447+
};
2448+
2449+
// we may try more than one; this is the final one, that worked and we are using
2450+
var finalMethod = '';
2451+
24342452
// Provide an "asm.js function" for the application, called to "link" the asm.js module. We instantiate
24352453
// the wasm module at that time, and it receives imports and provides exports and so forth, the app
24362454
// doesn't need to care that it is wasm or olyfilled wasm or asm.js.
@@ -2475,6 +2493,8 @@ function integrateWasmJS(Module) {
24752493
Module['printErr']('trying binaryen method: ' + curr);
24762494
#endif
24772495

2496+
finalMethod = curr;
2497+
24782498
if (curr === 'native-wasm') {
24792499
if (exports = doNativeWasm(global, env, providedBuffer)) break;
24802500
} else if (curr === 'asmjs') {

tests/benchmark_sse1.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -120,11 +120,11 @@ def strip_comments(text):
120120
charts_html = {}
121121
for result in native_results['results']:
122122
ch = result['chart']
123-
if not ch in charts_native: charts_native[ch] = []
123+
if ch not in charts_native: charts_native[ch] = []
124124
charts_native[ch] += [result]
125125
for result in html_results['results']:
126126
ch = result['chart']
127-
if not ch in charts_html: charts_html[ch] = []
127+
if ch not in charts_html: charts_html[ch] = []
128128
charts_html[ch] += [result]
129129

130130
def find_result_in_category(results, category):
@@ -298,4 +298,4 @@ def format_comparison(a, b):
298298
html += '</body></html>'
299299

300300
open('results_sse1.html', 'w').write(html)
301-
print 'Wrote ' + str(len(html)) + ' bytes to file results_sse1.html.'
301+
print 'Wrote ' + str(len(html)) + ' bytes to file results_sse1.html.'

tests/core/test_memorygrowth_3.c

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
#include <string.h>
4+
#include <unistd.h>
5+
#include <assert.h>
6+
#include "emscripten.h"
7+
8+
int get_TOTAL_MEMORY() {
9+
return EM_ASM_INT_V({ return TOTAL_MEMORY });
10+
}
11+
12+
typedef void* voidStar;
13+
14+
int main(int argc, char **argv)
15+
{
16+
int totalMemory = get_TOTAL_MEMORY();
17+
int chunk = 1024*1024;
18+
volatile voidStar alloc;
19+
#ifdef FAIL_REALLOC_BUFFER
20+
EM_ASM({
21+
Module.seenOurReallocBuffer = false;
22+
Module['reallocBuffer'] = function() {
23+
Module.seenOurReallocBuffer = true;
24+
return null;
25+
};
26+
});
27+
#endif
28+
for (int i = 0; i < (totalMemory/chunk)+2; i++) {
29+
// make sure state remains the same if malloc fails
30+
void* sbrk_before = sbrk(0);
31+
alloc = malloc(chunk);
32+
printf("%d : %d\n", i, !!alloc);
33+
if (alloc == NULL) {
34+
assert(sbrk(0) == sbrk_before);
35+
assert(totalMemory == get_TOTAL_MEMORY());
36+
break;
37+
}
38+
}
39+
assert(alloc == NULL);
40+
#ifdef FAIL_REALLOC_BUFFER
41+
EM_ASM({
42+
assert(Module.seenOurReallocBuffer, 'our override should have been called');
43+
});
44+
#endif
45+
puts("ok.");
46+
return 0;
47+
}

tests/core/test_memorygrowth_3.txt

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ok.

0 commit comments

Comments
 (0)