aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AUTHORS2
-rwxr-xr-xemcc18
-rw-r--r--src/analyzer.js7
-rw-r--r--src/embind/embind.js26
-rw-r--r--src/embind/emval.js15
-rw-r--r--src/library.js62
-rw-r--r--src/library_sdl.js5
-rw-r--r--src/settings.js5
-rw-r--r--system/include/emscripten/bind.h56
-rw-r--r--system/include/net/netinet/in.h7
-rw-r--r--system/include/sys/socket.h3
-rw-r--r--tests/cases/entry3.ll36
-rw-r--r--tests/cases/entry3.txt2
-rw-r--r--tests/embind/embind.test.js19
-rw-r--r--tests/embind/embind_test.cpp24
-rwxr-xr-xtests/runner.py97
-rw-r--r--tests/unistd/unlink.c165
-rw-r--r--tests/unistd/unlink.js7
-rw-r--r--tests/unistd/unlink.out42
-rw-r--r--tools/file_packager.py21
-rw-r--r--tools/find_bigfuncs.py13
-rw-r--r--tools/js-optimizer.js440
-rw-r--r--tools/test-js-optimizer-asm-outline-output.js570
-rw-r--r--tools/test-js-optimizer-asm-outline1-output.js566
-rw-r--r--tools/test-js-optimizer-asm-outline1.js234
-rw-r--r--tools/test-js-optimizer-asm-outline2-output.js728
-rw-r--r--tools/test-js-optimizer-asm-outline2.js (renamed from tools/test-js-optimizer-asm-outline.js)2
-rw-r--r--tools/test-js-optimizer-asm-pre-output.js8
28 files changed, 2276 insertions, 904 deletions
diff --git a/AUTHORS b/AUTHORS
index 8ebae515..ea4c8f0b 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -88,4 +88,6 @@ a license to everyone to use it as detailed in LICENSE.)
* Joseph Gentle <me@josephg.com>
* Douglas T. Crosher <dtc-moz@scieneer.com> (copyright owned by Mozilla Founcation)
* Soeren Balko <soeren.balko@gmail.com>
+* Ryan Kelly (ryan@rfk.id.au)
* Michael Lelli <toadking@toadking.com>
+
diff --git a/emcc b/emcc
index 895aab87..689e5a94 100755
--- a/emcc
+++ b/emcc
@@ -1538,14 +1538,17 @@ try:
# It is useful to run several js optimizer passes together, to save on unneeded unparsing/reparsing
js_optimizer_queue = []
+ js_optimizer_extra_info = {}
def flush_js_optimizer_queue():
- global final, js_optimizer_queue
+ global final, js_optimizer_queue, js_optimizer_extra_info
+ if len(js_optimizer_extra_info) == 0:
+ js_optimizer_extra_info = None
if len(js_optimizer_queue) > 0 and not(len(js_optimizer_queue) == 1 and js_optimizer_queue[0] == 'last'):
if DEBUG != '2':
if shared.Settings.ASM_JS:
js_optimizer_queue = ['asm'] + js_optimizer_queue
logging.debug('applying js optimization passes: %s', js_optimizer_queue)
- final = shared.Building.js_optimizer(final, js_optimizer_queue, jcache, debug_level >= 4)
+ final = shared.Building.js_optimizer(final, js_optimizer_queue, jcache, debug_level >= 4, js_optimizer_extra_info)
js_transform_tempfiles.append(final)
if DEBUG: save_intermediate('js_opts')
else:
@@ -1554,10 +1557,11 @@ try:
if shared.Settings.ASM_JS:
passes = ['asm'] + passes
logging.debug('applying js optimization pass: %s', passes)
- final = shared.Building.js_optimizer(final, passes, jcache, debug_level >= 4)
+ final = shared.Building.js_optimizer(final, passes, jcache, debug_level >= 4, js_optimizer_extra_info)
js_transform_tempfiles.append(final)
save_intermediate(name)
js_optimizer_queue = []
+ js_optimizer_extra_info = {}
if opt_level >= 1:
logging.debug('running pre-closure post-opts')
@@ -1574,7 +1578,7 @@ try:
else:
return 'eliminate'
- js_optimizer_queue += [get_eliminate(), 'simplifyExpressionsPre']
+ js_optimizer_queue += [get_eliminate(), 'simplifyExpressions']
if shared.Settings.RELOOP and not shared.Settings.ASM_JS:
js_optimizer_queue += ['optimizeShiftsAggressive', get_eliminate()] # aggressive shifts optimization requires loops, it breaks on switches
@@ -1588,9 +1592,9 @@ try:
final = shared.Building.closure_compiler(final)
if DEBUG: save_intermediate('closure')
- if opt_level >= 1:
- logging.debug('running post-closure post-opts')
- js_optimizer_queue += ['simplifyExpressionsPost']
+ if shared.Settings.OUTLINING_LIMIT > 0:
+ js_optimizer_queue += ['outline']
+ js_optimizer_extra_info['sizeToOutline'] = shared.Settings.OUTLINING_LIMIT
if (not closure or shared.Settings.ASM_JS) and shared.Settings.RELOOP and debug_level < 3:
js_optimizer_queue += ['registerize']
diff --git a/src/analyzer.js b/src/analyzer.js
index de9a7940..1d32d7fc 100644
--- a/src/analyzer.js
+++ b/src/analyzer.js
@@ -1433,15 +1433,14 @@ function analyzer(data, sidePass) {
func.labelsDict = {};
func.labelIds = {};
func.labelIdsInverse = {};
- func.labelIds[toNiceIdent('%0')] = 1;
- func.labelIdsInverse[0] = toNiceIdent('%0');
- func.labelIdCounter = 2;
+ func.labelIdCounter = 1;
func.labels.forEach(function(label) {
if (!(label.ident in func.labelIds)) {
func.labelIds[label.ident] = func.labelIdCounter++;
func.labelIdsInverse[func.labelIdCounter-1] = label.ident;
}
});
+ var entryIdent = func.labels[0].ident;
// Minify label ids to numeric ids.
func.labels.forEach(function(label) {
@@ -1478,7 +1477,7 @@ function analyzer(data, sidePass) {
function getActualLabelId(labelId) {
if (func.labelsDict[labelId]) return labelId;
// If not present, it must be a surprisingly-named entry (or undefined behavior, in which case, still ok to use the entry)
- labelId = func.labelIds[ENTRY_IDENT];
+ labelId = func.labelIds[entryIdent];
assert(func.labelsDict[labelId]);
return labelId;
}
diff --git a/src/embind/embind.js b/src/embind/embind.js
index 91386c69..f0cd0c74 100644
--- a/src/embind/embind.js
+++ b/src/embind/embind.js
@@ -5,9 +5,9 @@
/*global __emval_register, _emval_handle_array, __emval_decref*/
/*global ___getTypeName*/
/*jslint sub:true*/ /* The symbols 'fromWireType' and 'toWireType' must be accessed via array notation to be closure-safe since craftInvokerFunction crafts functions as strings that can't be closured. */
-var InternalError = Module.InternalError = extendError(Error, 'InternalError');
-var BindingError = Module.BindingError = extendError(Error, 'BindingError');
-var UnboundTypeError = Module.UnboundTypeError = extendError(BindingError, 'UnboundTypeError');
+var InternalError = Module['InternalError'] = extendError(Error, 'InternalError');
+var BindingError = Module['BindingError'] = extendError(Error, 'BindingError');
+var UnboundTypeError = Module['UnboundTypeError'] = extendError(BindingError, 'UnboundTypeError');
function throwInternalError(message) {
throw new InternalError(message);
@@ -638,7 +638,7 @@ function __embind_register_function(name, argCount, rawArgTypesAddr, rawInvoker,
var tupleRegistrations = {};
-function __embind_register_tuple(rawType, name, rawConstructor, rawDestructor) {
+function __embind_register_value_array(rawType, name, rawConstructor, rawDestructor) {
tupleRegistrations[rawType] = {
name: readLatin1String(name),
rawConstructor: FUNCTION_TABLE[rawConstructor],
@@ -647,7 +647,7 @@ function __embind_register_tuple(rawType, name, rawConstructor, rawDestructor) {
};
}
-function __embind_register_tuple_element(
+function __embind_register_value_array_element(
rawTupleType,
getterReturnType,
getter,
@@ -666,7 +666,7 @@ function __embind_register_tuple_element(
});
}
-function __embind_finalize_tuple(rawTupleType) {
+function __embind_finalize_value_array(rawTupleType) {
var reg = tupleRegistrations[rawTupleType];
delete tupleRegistrations[rawTupleType];
var elements = reg.elements;
@@ -725,7 +725,7 @@ function __embind_finalize_tuple(rawTupleType) {
var structRegistrations = {};
-function __embind_register_struct(
+function __embind_register_value_object(
rawType,
name,
rawConstructor,
@@ -739,7 +739,7 @@ function __embind_register_struct(
};
}
-function __embind_register_struct_field(
+function __embind_register_value_object_field(
structType,
fieldName,
getterReturnType,
@@ -760,7 +760,7 @@ function __embind_register_struct_field(
});
}
-function __embind_finalize_struct(structType) {
+function __embind_finalize_value_object(structType) {
var reg = structRegistrations[structType];
delete structRegistrations[structType];
@@ -879,11 +879,11 @@ var genericPointerToWireType = function(destructors, handle) {
if (handle.$$.smartPtrType === this) {
ptr = handle.$$.smartPtr;
} else {
- var clonedHandle = handle.clone();
+ var clonedHandle = handle['clone']();
ptr = this.rawShare(
ptr,
__emval_register(function() {
- clonedHandle.delete();
+ clonedHandle['delete']();
})
);
if (destructors !== null) {
@@ -1088,7 +1088,7 @@ function getInstanceTypeName(handle) {
return handle.$$.ptrType.registeredClass.name;
}
-ClassHandle.prototype.isAliasOf = function(other) {
+ClassHandle.prototype['isAliasOf'] = function(other) {
if (!(this instanceof ClassHandle)) {
return false;
}
@@ -1118,7 +1118,7 @@ function throwInstanceAlreadyDeleted(obj) {
throwBindingError(getInstanceTypeName(obj) + ' instance already deleted');
}
-ClassHandle.prototype.clone = function() {
+ClassHandle.prototype['clone'] = function() {
if (!this.$$.ptr) {
throwInstanceAlreadyDeleted(this);
}
diff --git a/src/embind/emval.js b/src/embind/emval.js
index 77270597..0d075188 100644
--- a/src/embind/emval.js
+++ b/src/embind/emval.js
@@ -4,6 +4,7 @@
/*global createNamedFunction*/
/*global readLatin1String, writeStringToMemory*/
/*global requireRegisteredType, throwBindingError*/
+/*jslint sub:true*/ /* The symbols 'fromWireType' and 'toWireType' must be accessed via array notation to be closure-safe since craftInvokerFunction crafts functions as strings that can't be closured. */
var Module = Module || {};
@@ -100,7 +101,7 @@ function __emval_new_cstring(v) {
function __emval_take_value(type, v) {
type = requireRegisteredType(type, '_emval_take_value');
- v = type.fromWireType(v);
+ v = type['fromWireType'](v);
return __emval_register(v);
}
@@ -203,7 +204,7 @@ function __emval_as(handle, returnType) {
returnType = requireRegisteredType(returnType, 'emval::as');
var destructors = [];
// caller owns destructing
- return returnType.toWireType(destructors, _emval_handle_array[handle].value);
+ return returnType['toWireType'](destructors, _emval_handle_array[handle].value);
}
function parseParameters(argCount, argTypes, argWireTypes) {
@@ -212,7 +213,7 @@ function parseParameters(argCount, argTypes, argWireTypes) {
var argType = requireRegisteredType(
HEAP32[(argTypes >> 2) + i],
"parameter " + i);
- a[i] = argType.fromWireType(argWireTypes[i]);
+ a[i] = argType['fromWireType'](argWireTypes[i]);
}
return a;
}
@@ -223,7 +224,7 @@ function __emval_call(handle, argCount, argTypes) {
var args = new Array(argCount);
for (var i = 0; i < argCount; ++i) {
- args[i] = types[i].fromWireType(arguments[3 + i]);
+ args[i] = types[i]['fromWireType'](arguments[3 + i]);
}
var fn = _emval_handle_array[handle].value;
@@ -247,8 +248,8 @@ function __emval_get_method_caller(argCount, argTypes) {
var retType = types[0];
var signatureName = retType.name + "_$" + types.slice(1).map(function (t) { return t.name; }).join("_") + "$";
- var args1 = ["Runtime", "createNamedFunction", "requireHandle", "getStringOrSymbol", "_emval_handle_array", "retType"];
- var args2 = [Runtime, createNamedFunction, requireHandle, getStringOrSymbol, _emval_handle_array, retType];
+ var args1 = ["addFunction", "createNamedFunction", "requireHandle", "getStringOrSymbol", "_emval_handle_array", "retType"];
+ var args2 = [Runtime.addFunction, createNamedFunction, requireHandle, getStringOrSymbol, _emval_handle_array, retType];
var argsList = ""; // 'arg0, arg1, arg2, ... , argN'
var argsListWired = ""; // 'arg0Wired, ..., argNWired'
@@ -260,7 +261,7 @@ function __emval_get_method_caller(argCount, argTypes) {
}
var invokerFnBody =
- "return Runtime.addFunction(createNamedFunction('" + signatureName + "', function (handle, name" + argsListWired + ") {\n" +
+ "return addFunction(createNamedFunction('" + signatureName + "', function (handle, name" + argsListWired + ") {\n" +
"requireHandle(handle);\n" +
"name = getStringOrSymbol(name);\n";
diff --git a/src/library.js b/src/library.js
index 66c4fa9a..a41c8105 100644
--- a/src/library.js
+++ b/src/library.js
@@ -1115,6 +1115,7 @@ LibraryManager.library = {
},
stat64: 'stat',
fstat64: 'fstat',
+ lstat64: 'lstat',
__01fstat64_: 'fstat',
__01stat64_: 'stat',
__01lstat64_: 'lstat',
@@ -1775,6 +1776,8 @@ LibraryManager.library = {
} else if (nbyte < 0 || offset < 0) {
___setErrNo(ERRNO_CODES.EINVAL);
return -1;
+ } else if (offset >= stream.object.contents.length) {
+ return 0;
} else {
var bytesRead = 0;
while (stream.ungotten.length && nbyte > 0) {
@@ -1784,6 +1787,8 @@ LibraryManager.library = {
}
var contents = stream.object.contents;
var size = Math.min(contents.length - offset, nbyte);
+ assert(size >= 0);
+
#if USE_TYPED_ARRAYS == 2
if (contents.subarray) { // typed array
HEAPU8.set(contents.subarray(offset, offset+size), buf);
@@ -1851,6 +1856,7 @@ LibraryManager.library = {
} else {
var ungotSize = stream.ungotten.length;
bytesRead = _pread(fildes, buf, nbyte, stream.position);
+ assert(bytesRead >= -1);
if (bytesRead != -1) {
stream.position += (stream.ungotten.length - ungotSize) + bytesRead;
}
@@ -1867,42 +1873,42 @@ LibraryManager.library = {
rmdir: function(path) {
// int rmdir(const char *path);
// http://pubs.opengroup.org/onlinepubs/000095399/functions/rmdir.html
- path = FS.analyzePath(Pointer_stringify(path));
+ path = Pointer_stringify(path);
+ path = FS.analyzePath(path, true);
if (!path.parentExists || !path.exists) {
___setErrNo(path.error);
return -1;
- } else if (!path.object.write || path.isRoot) {
+ } else if (!path.parentObject.write) {
___setErrNo(ERRNO_CODES.EACCES);
return -1;
} else if (!path.object.isFolder) {
___setErrNo(ERRNO_CODES.ENOTDIR);
return -1;
+ } else if (path.isRoot || path.path == FS.currentPath) {
+ ___setErrNo(ERRNO_CODES.EBUSY);
+ return -1;
} else {
for (var i in path.object.contents) {
___setErrNo(ERRNO_CODES.ENOTEMPTY);
return -1;
}
- if (path.path == FS.currentPath) {
- ___setErrNo(ERRNO_CODES.EBUSY);
- return -1;
- } else {
- delete path.parentObject.contents[path.name];
- return 0;
- }
+ delete path.parentObject.contents[path.name];
+ return 0;
}
},
unlink__deps: ['$FS', '__setErrNo', '$ERRNO_CODES'],
unlink: function(path) {
// int unlink(const char *path);
// http://pubs.opengroup.org/onlinepubs/000095399/functions/unlink.html
- path = FS.analyzePath(Pointer_stringify(path));
+ path = Pointer_stringify(path);
+ path = FS.analyzePath(path, true);
if (!path.parentExists || !path.exists) {
___setErrNo(path.error);
return -1;
} else if (path.object.isFolder) {
- ___setErrNo(ERRNO_CODES.EISDIR);
+ ___setErrNo(ERRNO_CODES.EPERM);
return -1;
- } else if (!path.object.write) {
+ } else if (!path.parentObject.write) {
___setErrNo(ERRNO_CODES.EACCES);
return -1;
} else {
@@ -2559,15 +2565,27 @@ LibraryManager.library = {
continue;
}
- // TODO: Support strings like "%5c" etc.
- if (format[formatIndex] === '%' && format[formatIndex+1] == 'c') {
- var argPtr = {{{ makeGetValue('varargs', 'argIndex', 'void*') }}};
- argIndex += Runtime.getAlignSize('void*', null, true);
- fields++;
- next = get();
- {{{ makeSetValue('argPtr', 0, 'next', 'i8') }}}
- formatIndex += 2;
- continue;
+ if (format[formatIndex] === '%') {
+ var nextC = format.indexOf('c', formatIndex+1);
+ if (nextC > 0) {
+ var maxx = 1;
+ if (nextC > formatIndex+1) {
+ var sub = format.substring(formatIndex+1, nextC)
+ maxx = parseInt(sub);
+ if (maxx != sub) maxx = 0;
+ }
+ if (maxx) {
+ var argPtr = HEAP32[(varargs + argIndex)>>2];
+ argIndex += Runtime.getAlignSize('void*', null, true);
+ fields++;
+ for (var i = 0; i < maxx; i++) {
+ next = get();
+ {{{ makeSetValue('argPtr++', 0, 'next', 'i8') }}};
+ }
+ formatIndex += nextC - formatIndex + 1;
+ continue;
+ }
+ }
}
// remove whitespace
@@ -5957,7 +5975,7 @@ LibraryManager.library = {
return 1;
} else {
var lib_record = DLFCN_DATA.loadedLibs[handle];
- if (lib_record.refcount-- == 0) {
+ if (--lib_record.refcount == 0) {
delete DLFCN_DATA.loadedLibNames[lib_record.name];
delete DLFCN_DATA.loadedLibs[handle];
}
diff --git a/src/library_sdl.js b/src/library_sdl.js
index d14e433b..9287bd3e 100644
--- a/src/library_sdl.js
+++ b/src/library_sdl.js
@@ -939,7 +939,10 @@ var LibrarySDL = {
// TODO
},
- SDL_GetKeyboardState: function() {
+ SDL_GetKeyboardState: function(numKeys) {
+ if (numKeys) {
+ {{{ makeSetValue('numKeys', 0, 0x10000, 'i32') }}};
+ }
return SDL.keyboardState;
},
diff --git a/src/settings.js b/src/settings.js
index 10e93975..b33ea7b3 100644
--- a/src/settings.js
+++ b/src/settings.js
@@ -125,6 +125,11 @@ var INLINING_LIMIT = 0; // A limit on inlining. If 0, we will inline normally i
// we will prevent inlining of functions of this size or larger
// in closure. 50 is a reasonable setting if you do not want
// inlining
+var OUTLINING_LIMIT = 0; // A function size above which we try to automatically break up
+ // functions into smaller ones, to avoid the downsides of very
+ // large functions (JS engines often compile them very slowly,
+ // compile them with lower optimizations, or do not optimize them
+ // at all). If 0, we do not perform outlining at all.
// Generated code debugging options
var SAFE_HEAP = 0; // Check each write to the heap, for example, this will give a clear
diff --git a/system/include/emscripten/bind.h b/system/include/emscripten/bind.h
index cd465e45..403d8084 100644
--- a/system/include/emscripten/bind.h
+++ b/system/include/emscripten/bind.h
@@ -70,13 +70,13 @@ namespace emscripten {
GenericFunction invoker,
GenericFunction function);
- void _embind_register_tuple(
+ void _embind_register_value_array(
TYPEID tupleType,
const char* name,
GenericFunction constructor,
GenericFunction destructor);
- void _embind_register_tuple_element(
+ void _embind_register_value_array_element(
TYPEID tupleType,
TYPEID getterReturnType,
GenericFunction getter,
@@ -85,15 +85,15 @@ namespace emscripten {
GenericFunction setter,
void* setterContext);
- void _embind_finalize_tuple(TYPEID tupleType);
+ void _embind_finalize_value_array(TYPEID tupleType);
- void _embind_register_struct(
+ void _embind_register_value_object(
TYPEID structType,
const char* fieldName,
GenericFunction constructor,
GenericFunction destructor);
- void _embind_register_struct_field(
+ void _embind_register_value_object_field(
TYPEID structType,
const char* fieldName,
TYPEID getterReturnType,
@@ -103,7 +103,7 @@ namespace emscripten {
GenericFunction setter,
void* setterContext);
- void _embind_finalize_struct(TYPEID structType);
+ void _embind_finalize_value_object(TYPEID structType);
void _embind_register_smart_ptr(
TYPEID pointerType,
@@ -531,26 +531,26 @@ namespace emscripten {
////////////////////////////////////////////////////////////////////////////////
template<typename ClassType>
- class value_tuple : public internal::noncopyable {
+ class value_array : public internal::noncopyable {
public:
- value_tuple(const char* name) {
+ value_array(const char* name) {
using namespace internal;
- _embind_register_tuple(
+ _embind_register_value_array(
TypeID<ClassType>::get(),
name,
reinterpret_cast<GenericFunction>(&raw_constructor<ClassType>),
reinterpret_cast<GenericFunction>(&raw_destructor<ClassType>));
}
- ~value_tuple() {
+ ~value_array() {
using namespace internal;
- _embind_finalize_tuple(TypeID<ClassType>::get());
+ _embind_finalize_value_array(TypeID<ClassType>::get());
}
template<typename InstanceType, typename ElementType>
- value_tuple& element(ElementType InstanceType::*field) {
+ value_array& element(ElementType InstanceType::*field) {
using namespace internal;
- _embind_register_tuple_element(
+ _embind_register_value_array_element(
TypeID<ClassType>::get(),
TypeID<ElementType>::get(),
reinterpret_cast<GenericFunction>(
@@ -566,11 +566,11 @@ namespace emscripten {
}
template<typename Getter, typename Setter>
- value_tuple& element(Getter getter, Setter setter) {
+ value_array& element(Getter getter, Setter setter) {
using namespace internal;
typedef GetterPolicy<Getter> GP;
typedef SetterPolicy<Setter> SP;
- _embind_register_tuple_element(
+ _embind_register_value_array_element(
TypeID<ClassType>::get(),
TypeID<typename GP::ReturnType>::get(),
reinterpret_cast<GenericFunction>(&GP::template get<ClassType>),
@@ -582,11 +582,11 @@ namespace emscripten {
}
template<int Index>
- value_tuple& element(index<Index>) {
+ value_array& element(index<Index>) {
using namespace internal;
ClassType* null = 0;
typedef typename std::remove_reference<decltype((*null)[Index])>::type ElementType;
- _embind_register_tuple_element(
+ _embind_register_value_array_element(
TypeID<ClassType>::get(),
TypeID<ElementType>::get(),
reinterpret_cast<GenericFunction>(&internal::get_by_index<ClassType, ElementType>),
@@ -603,25 +603,25 @@ namespace emscripten {
////////////////////////////////////////////////////////////////////////////////
template<typename ClassType>
- class value_struct : public internal::noncopyable {
+ class value_object : public internal::noncopyable {
public:
- value_struct(const char* name) {
+ value_object(const char* name) {
using namespace internal;
- _embind_register_struct(
+ _embind_register_value_object(
TypeID<ClassType>::get(),
name,
reinterpret_cast<GenericFunction>(&raw_constructor<ClassType>),
reinterpret_cast<GenericFunction>(&raw_destructor<ClassType>));
}
- ~value_struct() {
- _embind_finalize_struct(internal::TypeID<ClassType>::get());
+ ~value_object() {
+ _embind_finalize_value_object(internal::TypeID<ClassType>::get());
}
template<typename InstanceType, typename FieldType>
- value_struct& field(const char* fieldName, FieldType InstanceType::*field) {
+ value_object& field(const char* fieldName, FieldType InstanceType::*field) {
using namespace internal;
- _embind_register_struct_field(
+ _embind_register_value_object_field(
TypeID<ClassType>::get(),
fieldName,
TypeID<FieldType>::get(),
@@ -638,7 +638,7 @@ namespace emscripten {
}
template<typename Getter, typename Setter>
- value_struct& field(
+ value_object& field(
const char* fieldName,
Getter getter,
Setter setter
@@ -646,7 +646,7 @@ namespace emscripten {
using namespace internal;
typedef GetterPolicy<Getter> GP;
typedef SetterPolicy<Setter> SP;
- _embind_register_struct_field(
+ _embind_register_value_object_field(
TypeID<ClassType>::get(),
fieldName,
TypeID<typename GP::ReturnType>::get(),
@@ -659,11 +659,11 @@ namespace emscripten {
}
template<int Index>
- value_struct& field(const char* fieldName, index<Index>) {
+ value_object& field(const char* fieldName, index<Index>) {
using namespace internal;
ClassType* null = 0;
typedef typename std::remove_reference<decltype((*null)[Index])>::type ElementType;
- _embind_register_struct_field(
+ _embind_register_value_object_field(
TypeID<ClassType>::get(),
fieldName,
TypeID<ElementType>::get(),
diff --git a/system/include/net/netinet/in.h b/system/include/net/netinet/in.h
index cf324f3d..fba1a7b3 100644
--- a/system/include/net/netinet/in.h
+++ b/system/include/net/netinet/in.h
@@ -55,6 +55,13 @@ extern const struct in6_addr in6addr_interfacelocal_allnodes;
extern const struct in6_addr in6addr_interfacelocal_allrouters;
extern const struct in6_addr in6addr_sitelocal_allrouters;
+#define IN6ADDR_ANY_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } }
+#define IN6ADDR_LOOPBACK_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } } }
+#define IN6ADDR_LINKLOCAL_ALLNODES_INIT \
+ { { { 0xff,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } } }
+#define IN6ADDR_LINKLOCAL_ALLROUTERS_INIT \
+ { { { 0xff,2,0,0,0,0,0,0,0,0,0,0,0,0,0,2 } } }
+
struct sockaddr_in6 {
int sin6_family;
unsigned short sin6_port;
diff --git a/system/include/sys/socket.h b/system/include/sys/socket.h
index 3168f85b..9650bb9a 100644
--- a/system/include/sys/socket.h
+++ b/system/include/sys/socket.h
@@ -34,7 +34,8 @@ extern "C" {
#define SO_LINGER 130
#define SO_BSDCOMPAT 140
-#define SHUT_RD 1
+#define SHUT_RD 0
+#define SHUT_WR 1
#define SHUT_RDWR 2
typedef unsigned int sa_family_t;
diff --git a/tests/cases/entry3.ll b/tests/cases/entry3.ll
new file mode 100644
index 00000000..a20c6843
--- /dev/null
+++ b/tests/cases/entry3.ll
@@ -0,0 +1,36 @@
+; ModuleID = '/tmp/tmpKnA2D3/a.out.bc'
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32-S128"
+target triple = "i386-pc-linux-gnu"
+
+@.str = private unnamed_addr constant [11 x i8] c"getgid=%d\0A\00", align 1
+@.str1 = private unnamed_addr constant [6 x i8] c"f=%d\0A\00", align 1
+
+define internal i32 @_Z1fii(i32, i32) noinline {
+entry:
+ %3 = tail call i32 @getgid()
+ %4 = icmp eq i32 %3, 0
+ br i1 %4, label %cond.b, label %cond.a
+
+cond.a:
+ %6 = tail call i32 @getgid()
+ br label %cond.end
+
+cond.b:
+ br label %cond.end
+
+cond.end:
+ %.0 = phi i32 [ 0, %cond.b ], [ 1, %1 ]
+ ret i32 %.0
+}
+
+declare i32 @getgid()
+
+define i32 @main() {
+ %1 = tail call i32 @getgid()
+ %2 = tail call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([11 x i8]* @.str, i32 0, i32 0), i32 %1)
+ %3 = tail call i32 @_Z1fii(i32 undef, i32 undef)
+ %4 = tail call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([6 x i8]* @.str1, i32 0, i32 0), i32 %3)
+ ret i32 0
+}
+
+declare i32 @printf(i8* nocapture, ...) nounwind
diff --git a/tests/cases/entry3.txt b/tests/cases/entry3.txt
new file mode 100644
index 00000000..4060fb06
--- /dev/null
+++ b/tests/cases/entry3.txt
@@ -0,0 +1,2 @@
+getgid=0
+f=0
diff --git a/tests/embind/embind.test.js b/tests/embind/embind.test.js
index e60e1ab3..da81a81e 100644
--- a/tests/embind/embind.test.js
+++ b/tests/embind/embind.test.js
@@ -898,10 +898,7 @@ module({
test("can clone handles", function() {
var a = cm.emval_test_get_function_ptr();
- assert.equal(1, a.$$.count.value);
var b = a.clone();
- assert.equal(2, a.$$.count.value);
- assert.equal(2, b.$$.count.value);
a.delete();
assert.throws(cm.BindingError, function() {
@@ -1149,7 +1146,7 @@ module({
a.set(b);
var c = a.get();
- assert.equal(b.