diff options
30 files changed, 2320 insertions, 910 deletions
@@ -88,3 +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> + @@ -1046,7 +1046,7 @@ try: if shared.Settings.CORRECT_SIGNS >= 2 or shared.Settings.CORRECT_OVERFLOWS >= 2 or shared.Settings.CORRECT_ROUNDINGS >= 2: debug_level = 4 # must keep debug info to do line-by-line operations - if debug_level > 0 and closure: + if debug_level > 1 and closure: logging.warning('disabling closure because debug info was requested') closure = False @@ -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 5e58f011..22cc053e 100644 --- a/src/library.js +++ b/src/library.js @@ -1118,6 +1118,7 @@ LibraryManager.library = { }, stat64: 'stat', fstat64: 'fstat', + lstat64: 'lstat', __01fstat64_: 'fstat', __01stat64_: 'stat', __01lstat64_: 'lstat', @@ -1778,6 +1779,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) { @@ -1787,6 +1790,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); @@ -1854,6 +1859,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; } @@ -1870,42 +1876,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 { @@ -2562,15 +2568,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 @@ -4901,7 +4919,9 @@ LibraryManager.library = { isprint: function(chr) { return 0x1F < chr && chr < 0x7F; }, - isgraph: 'isprint', + isgraph: function(chr) { + return 0x20 < chr && chr < 0x7F; + }, // Lookup tables for glibc ctype implementation. __ctype_b_loc: function() { // http://refspecs.freestandards.org/LSB_3.0.0/LSB-Core-generic/LSB-Core-generic/baselib---ctype-b-loc.html @@ -5958,7 +5978,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/parseTools.js b/src/parseTools.js index eb200c65..a5785e27 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -1231,7 +1231,7 @@ function indexizeFunctions(value, type) { // add signature to library functions that we now know need indexing var sig = Functions.implementedFunctions[value] || Functions.unimplementedFunctions[value]; if (!sig) { - sig = Functions.unimplementedFunctions[value] = Functions.getSignature(out.returnType, out.segments ? out.segments.map(function(segment) { return segment[0].text }) : []); + sig = Functions.unimplementedFunctions[value] = Functions.getSignature(out.returnType, out.segments ? out.segments.map(function(segment) { return segment[0].text }) : [], isVarArgsFunctionType(type)); } return Functions.getIndex(value, undefined, sig); } diff --git a/src/preamble.js b/src/preamble.js index c9e7e4eb..41017676 100644 --- a/src/preamble.js +++ b/src/preamble.js @@ -784,7 +784,7 @@ Module['writeArrayToMemory'] = writeArrayToMemory; {{{ reSign }}} #if PRECISE_I32_MUL -if (!Math['imul']) Math['imul'] = function(a, b) { +if (!Math.imul) Math.imul = function(a, b) { var ah = a >>> 16; var al = a & 0xffff; var bh = b >>> 16; @@ -792,7 +792,7 @@ if (!Math['imul']) Math['imul'] = function(a, b) { return (al*bl + ((ah*bl + al*bh) << 16))|0; }; #else -Math['imul'] = function(a, b) { +Math.imul = function(a, b) { return (a*b)|0; // fast but imprecise }; #endif 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; |