From: Ryan Hyun Choi Date: Fri, 17 Sep 2021 00:32:00 +0000 (+0900) Subject: LWNode_Release_210917_1fb131f X-Git-Tag: accepted/tizen/unified/20210917.060807^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F89%2F264389%2F1;p=platform%2Fframework%2Fweb%2Flwnode.git LWNode_Release_210917_1fb131f Change-Id: I3d363478c36160a38c24c97f776b3fe6770ed02c Signed-off-by: Ryan Choi --- diff --git a/lwnode/code/escargotshim/common.gypi b/lwnode/code/escargotshim/common.gypi index 5a93981..5f64ff6 100755 --- a/lwnode/code/escargotshim/common.gypi +++ b/lwnode/code/escargotshim/common.gypi @@ -29,6 +29,13 @@ 'cflags': [ '-Wfatal-errors', '-Os' ], }, }, + 'all_dependent_settings': { + 'configurations': { + 'Release': { + 'defines': ['NDEBUG'], + }, + }, + }, 'conditions': [ ['target_os=="tizen"', { 'target_defaults': { diff --git a/lwnode/code/escargotshim/deps/escargot/build/target.cmake b/lwnode/code/escargotshim/deps/escargot/build/target.cmake index 763e1c0..0ccf7d9 100644 --- a/lwnode/code/escargotshim/deps/escargot/build/target.cmake +++ b/lwnode/code/escargotshim/deps/escargot/build/target.cmake @@ -11,7 +11,7 @@ SET (ESCARGOT_BUILD_32BIT OFF) IF (${ESCARGOT_HOST} STREQUAL "linux") # default set of LDFLAGS SET (ESCARGOT_LDFLAGS -lpthread -lrt -Wl,--gc-sections) - IF (${ESCARGOT_ARCH} STREQUAL "x64") + IF ((${ESCARGOT_ARCH} STREQUAL "x64") OR (${ESCARGOT_ARCH} STREQUAL "x86_64")) ELSEIF ((${ESCARGOT_ARCH} STREQUAL "x86") OR (${ESCARGOT_ARCH} STREQUAL "i686")) SET (ESCARGOT_BUILD_32BIT ON) SET (ESCARGOT_CXXFLAGS ${ESCARGOT_CXXFLAGS} -m32 -mfpmath=sse -msse -msse2) @@ -28,7 +28,7 @@ ELSEIF (${ESCARGOT_HOST} STREQUAL "tizen_obs") # default set of LDFLAGS SET (ESCARGOT_LDFLAGS -lpthread -lrt -Wl,--gc-sections) SET (ESCARGOT_DEFINITIONS -DESCARGOT_TIZEN) - IF (${ESCARGOT_ARCH} STREQUAL "x64") + IF ((${ESCARGOT_ARCH} STREQUAL "x64") OR (${ESCARGOT_ARCH} STREQUAL "x86_64")) ELSEIF ((${ESCARGOT_ARCH} STREQUAL "x86") OR (${ESCARGOT_ARCH} STREQUAL "i686")) SET (ESCARGOT_BUILD_32BIT ON) SET (ESCARGOT_CXXFLAGS ${ESCARGOT_CXXFLAGS} -m32 -mfpmath=sse -msse -msse2) diff --git a/lwnode/code/escargotshim/deps/escargot/src/Escargot.h b/lwnode/code/escargotshim/deps/escargot/src/Escargot.h index d9e3db6..77974ef 100755 --- a/lwnode/code/escargotshim/deps/escargot/src/Escargot.h +++ b/lwnode/code/escargotshim/deps/escargot/src/Escargot.h @@ -227,6 +227,7 @@ #include #include #include +#include #endif extern "C" { diff --git a/lwnode/code/escargotshim/deps/escargot/src/api/EscargotPublic.cpp b/lwnode/code/escargotshim/deps/escargot/src/api/EscargotPublic.cpp index 0e9a964..7e3c1c2 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/api/EscargotPublic.cpp +++ b/lwnode/code/escargotshim/deps/escargot/src/api/EscargotPublic.cpp @@ -168,6 +168,11 @@ public: m_platform->hostImportModuleDynamically(toRef(relatedContext), toRef(referrer), toRef(src), toRef(promise)); } + virtual bool canBlockExecution(Context* relatedContext) override + { + return m_platform->canBlockExecution(toRef(relatedContext)); + } + virtual void* allocateThreadLocalCustomData() override { return m_platform->allocateThreadLocalCustomData(); @@ -2261,8 +2266,11 @@ GCManagedVector ExecutionStateRef::computeStackTraceD locData = iterMap->second; } + InterpretedCodeBlock* codeBlock = byteCodeBlock->codeBlock(); size_t byteCodePosition = stackTraceData[i].second.loc.byteCodePosition; stackTraceData[i].second.loc = byteCodeBlock->computeNodeLOCFromByteCode(state->context(), byteCodePosition, byteCodeBlock->m_codeBlock, locData); + stackTraceData[i].second.src = codeBlock->script()->srcName(); + stackTraceData[i].second.sourceCode = codeBlock->script()->sourceCode(); } Evaluator::StackTraceData t; diff --git a/lwnode/code/escargotshim/deps/escargot/src/api/EscargotPublic.h b/lwnode/code/escargotshim/deps/escargot/src/api/EscargotPublic.h index 216bbb1..2014b38 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/api/EscargotPublic.h +++ b/lwnode/code/escargotshim/deps/escargot/src/api/EscargotPublic.h @@ -1888,6 +1888,11 @@ public: } void notifyHostImportModuleDynamicallyResult(ContextRef* relatedContext, ScriptRef* referrer, StringRef* src, PromiseObjectRef* promise, LoadModuleResult loadModuleResult); + virtual bool canBlockExecution(ContextRef* relatedContext) + { + return true; + } + // ThreadLocal custom data // PlatformRef should not have any member variables // Instead, user could allocate thread-local values through following methods diff --git a/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinArray.cpp b/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinArray.cpp index 83aec02..4965259 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinArray.cpp +++ b/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinArray.cpp @@ -693,17 +693,6 @@ static Value builtinArraySplice(ExecutionState& state, Value thisValue, size_t a return A; } - -static Value builtinArrayToString(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - RESOLVE_THIS_BINDING_TO_OBJECT(thisObject, Array, toString); - Value toString = thisObject->get(state, state.context()->staticStrings().join).value(state, thisObject); - if (!toString.isCallable()) { - toString = state.context()->globalObject()->objectPrototypeToString(); - } - return Object::call(state, toString, thisObject, 0, nullptr); -} - static Value builtinArrayConcat(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) { RESOLVE_THIS_BINDING_TO_OBJECT(thisObject, Array, concat); @@ -1685,29 +1674,27 @@ static Value builtinArrayUnshift(ExecutionState& state, Value thisValue, size_t // Array.prototype.find ( predicate [ , thisArg ] )# static Value builtinArrayFind(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) { + Value predicate = argv[0]; + Value thisArg = argc > 1 ? argv[1] : Value(); // Let O be ? ToObject(this value). RESOLVE_THIS_BINDING_TO_OBJECT(O, Array, find); // Let len be ? ToLength(? Get(O, "length")). - double len = O->length(state); + uint64_t len = O->length(state); // If IsCallable(predicate) is false, throw a TypeError exception. - if (!argv[0].isCallable()) { + if (!predicate.isCallable()) { ErrorObject::throwBuiltinError(state, ErrorObject::TypeError, state.context()->staticStrings().Array.string(), true, state.context()->staticStrings().find.string(), ErrorObject::Messages::GlobalObject_CallbackNotCallable); } - Value T; - // If thisArg was supplied, let T be thisArg; else let T be undefined. - if (argc >= 2) { - T = argv[1]; - } + // Let k be 0. - double k = 0; + uint64_t k = 0; // Repeat, while k < len while (k < len) { // Let Pk be ! ToString(k). // Let kValue be ? Get(O, Pk). Value kValue = O->get(state, ObjectPropertyName(state, Value(k))).value(state, O); - // Let testResult be ToBoolean(? Call(predicate, T, « kValue, k, O »)). + // Let testResult be ToBoolean(? Call(predicate, thisArg, « kValue, k, O »)). Value v[] = { kValue, Value(k), O }; - bool testResult = Object::call(state, argv[0], T, 3, v).toBoolean(state); + bool testResult = Object::call(state, argv[0], thisArg, 3, v).toBoolean(state); // If testResult is true, return kValue. if (testResult) { return kValue; @@ -1722,29 +1709,27 @@ static Value builtinArrayFind(ExecutionState& state, Value thisValue, size_t arg // Array.prototype.findIndex ( predicate [ , thisArg ] )# static Value builtinArrayFindIndex(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) { + Value predicate = argv[0]; + Value thisArg = argc > 1 ? argv[1] : Value(); // Let O be ? ToObject(this value). RESOLVE_THIS_BINDING_TO_OBJECT(O, Array, findIndex); // Let len be ? ToLength(? Get(O, "length")). - double len = O->length(state); + uint64_t len = O->length(state); // If IsCallable(predicate) is false, throw a TypeError exception. - if (!argv[0].isCallable()) { + if (!predicate.isCallable()) { ErrorObject::throwBuiltinError(state, ErrorObject::TypeError, state.context()->staticStrings().Array.string(), true, state.context()->staticStrings().findIndex.string(), ErrorObject::Messages::GlobalObject_CallbackNotCallable); } - Value T; - // If thisArg was supplied, let T be thisArg; else let T be undefined. - if (argc >= 2) { - T = argv[1]; - } + // Let k be 0. - double k = 0; + uint64_t k = 0; // Repeat, while k < len while (k < len) { // Let Pk be ! ToString(k). // Let kValue be ? Get(O, Pk). Value kValue = O->get(state, ObjectPropertyName(state, Value(k))).value(state, O); - // Let testResult be ToBoolean(? Call(predicate, T, « kValue, k, O »)). + // Let testResult be ToBoolean(? Call(predicate, thisArg, « kValue, k, O »)). Value v[] = { kValue, Value(k), O }; - bool testResult = Object::call(state, argv[0], T, 3, v).toBoolean(state); + bool testResult = Object::call(state, argv[0], thisArg, 3, v).toBoolean(state); // If testResult is true, return k. if (testResult) { return Value(k); @@ -1848,7 +1833,7 @@ static Value builtinArrayIteratorNext(ExecutionState& state, Value thisValue, si static Value builtinArrayAt(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) { - RESOLVE_THIS_BINDING_TO_OBJECT(obj, Array, entries); + RESOLVE_THIS_BINDING_TO_OBJECT(obj, Array, at); size_t len = obj->length(state); double relativeStart = argv[0].toInteger(state); if (relativeStart < 0) { @@ -1860,8 +1845,95 @@ static Value builtinArrayAt(ExecutionState& state, Value thisValue, size_t argc, return obj->getIndexedProperty(state, Value(relativeStart)).value(state, thisValue); } +static Value builtinArrayFindLast(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) +{ + // https://tc39.es/proposal-array-find-from-last/index.html#sec-array.prototype.findlast + Value predicate = argv[0]; + Value thisArg = argc > 1 ? argv[1] : Value(); + // 1. Let O be ? ToObject(this value). + RESOLVE_THIS_BINDING_TO_OBJECT(O, Array, findLast); + // 2. Let len be ? LengthOfArrayLike(O). + int64_t len = static_cast(O->length(state)); + // 3. If IsCallable(predicate) is false, throw a TypeError exception. + if (!predicate.isCallable()) { + ErrorObject::throwBuiltinError(state, ErrorObject::TypeError, state.context()->staticStrings().Array.string(), true, state.context()->staticStrings().findLast.string(), ErrorObject::Messages::GlobalObject_CallbackNotCallable); + } + // 4. Let k be len - 1. + int64_t k = len - 1; + // 5. Repeat, while k ≥ 0, + while (k >= 0) { + // a. Let Pk be ! ToString(𝔽(k)). + // b. Let kValue be ? Get(O, Pk). + Value kValue = O->getIndexedProperty(state, Value(k)).value(state, O); + // c. Let testResult be ! ToBoolean(? Call(predicate, thisArg, « kValue, 𝔽(k), O »)). + Value predicateArgv[] = { + kValue, Value(k), Value(O) + }; + bool testResult = Object::call(state, predicate, thisArg, 3, predicateArgv).toBoolean(state); + // d. If testResult is true, return kValue. + if (testResult) { + return kValue; + } + // e. Set k to k - 1. + k--; + } + + return Value(); +} + +static Value builtinArrayFindLastIndex(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) +{ + // https://tc39.es/proposal-array-find-from-last/index.html#sec-array.prototype.findlastindex + Value predicate = argv[0]; + Value thisArg = argc > 1 ? argv[1] : Value(); + // 1. Let O be ? ToObject(this value). + RESOLVE_THIS_BINDING_TO_OBJECT(O, Array, findLastIndex); + // 2. Let len be ? LengthOfArrayLike(O). + int64_t len = static_cast(O->length(state)); + // 3. If IsCallable(predicate) is false, throw a TypeError exception. + if (!predicate.isCallable()) { + ErrorObject::throwBuiltinError(state, ErrorObject::TypeError, state.context()->staticStrings().Array.string(), true, state.context()->staticStrings().findLastIndex.string(), ErrorObject::Messages::GlobalObject_CallbackNotCallable); + } + // 4. Let k be len - 1. + int64_t k = len - 1; + // 5. Repeat, while k ≥ 0, + while (k >= 0) { + // a. Let Pk be ! ToString(𝔽(k)). + // b. Let kValue be ? Get(O, Pk). + Value kValue = O->getIndexedProperty(state, Value(k)).value(state, O); + // c. Let testResult be ! ToBoolean(? Call(predicate, thisArg, « kValue, 𝔽(k), O »)). + Value predicateArgv[] = { + kValue, Value(k), Value(O) + }; + bool testResult = Object::call(state, predicate, thisArg, 3, predicateArgv).toBoolean(state); + // d. If testResult is true, return kValue. + if (testResult) { + return Value(k); + } + // e. Set k to k - 1. + k--; + } + + return Value(-1); +} + +void GlobalObject::initializeArray(ExecutionState& state) +{ + ObjectPropertyNativeGetterSetterData* nativeData = new ObjectPropertyNativeGetterSetterData(true, false, true, + [](ExecutionState& state, Object* self, const Value& receiver, const EncodedValue& privateDataFromObjectPrivateArea) -> Value { + ASSERT(self->isGlobalObject()); + return self->asGlobalObject()->array(); + }, + nullptr); + + defineNativeDataAccessorProperty(state, ObjectPropertyName(state.context()->staticStrings().Array), nativeData, Value(Value::EmptyValue)); +} + void GlobalObject::installArray(ExecutionState& state) { + ASSERT(!!m_iteratorPrototype); + ASSERT(!!m_arrayToString); + m_array = new NativeFunctionObject(state, NativeFunctionInfo(state.context()->staticStrings().Array, builtinArrayConstructor, 1), NativeFunctionObject::__ForBuiltinConstructor__); m_array->setGlobalIntrinsicObject(state); @@ -1922,8 +1994,9 @@ void GlobalObject::installArray(ExecutionState& state) ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(state.context()->staticStrings().shift, builtinArrayShift, 0, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); m_arrayPrototype->defineOwnPropertyThrowsException(state, ObjectPropertyName(state.context()->staticStrings().reverse), ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(state.context()->staticStrings().reverse, builtinArrayReverse, 0, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); + m_arrayPrototype->defineOwnPropertyThrowsException(state, ObjectPropertyName(state.context()->staticStrings().toString), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(state.context()->staticStrings().toString, builtinArrayToString, 0, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); + ObjectPropertyDescriptor(m_arrayToString, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); m_arrayPrototype->defineOwnPropertyThrowsException(state, ObjectPropertyName(state.context()->staticStrings().map), ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(state.context()->staticStrings().map, builtinArrayMap, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); m_arrayPrototype->defineOwnPropertyThrowsException(state, ObjectPropertyName(state.context()->staticStrings().some), @@ -1946,7 +2019,10 @@ void GlobalObject::installArray(ExecutionState& state) ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(state.context()->staticStrings().flatMap, builtinArrayFlatMap, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); m_arrayPrototype->defineOwnPropertyThrowsException(state, ObjectPropertyName(state.context()->staticStrings().at), ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(state.context()->staticStrings().at, builtinArrayAt, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - + m_arrayPrototype->defineOwnPropertyThrowsException(state, ObjectPropertyName(state.context()->staticStrings().findLast), + ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(state.context()->staticStrings().findLast, builtinArrayFindLast, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); + m_arrayPrototype->defineOwnPropertyThrowsException(state, ObjectPropertyName(state.context()->staticStrings().findLastIndex), + ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(state.context()->staticStrings().findLastIndex, builtinArrayFindLastIndex, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); Object* blackList = new Object(state); blackList->markThisObjectDontNeedStructureTransitionTable(); @@ -1956,6 +2032,8 @@ void GlobalObject::installArray(ExecutionState& state) blackList->defineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().entries), ObjectPropertyDescriptor(Value(true), ObjectPropertyDescriptor::AllPresent)); blackList->defineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().fill), ObjectPropertyDescriptor(Value(true), ObjectPropertyDescriptor::AllPresent)); blackList->defineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().find), ObjectPropertyDescriptor(Value(true), ObjectPropertyDescriptor::AllPresent)); + blackList->defineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().findLast), ObjectPropertyDescriptor(Value(true), ObjectPropertyDescriptor::AllPresent)); + blackList->defineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().findLastIndex), ObjectPropertyDescriptor(Value(true), ObjectPropertyDescriptor::AllPresent)); blackList->defineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().findIndex), ObjectPropertyDescriptor(Value(true), ObjectPropertyDescriptor::AllPresent)); blackList->defineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().keys), ObjectPropertyDescriptor(Value(true), ObjectPropertyDescriptor::AllPresent)); blackList->defineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().values), ObjectPropertyDescriptor(Value(true), ObjectPropertyDescriptor::AllPresent)); @@ -1990,7 +2068,7 @@ void GlobalObject::installArray(ExecutionState& state) m_arrayIteratorPrototype->defineOwnPropertyThrowsException(state, ObjectPropertyName(state.context()->vmInstance()->globalSymbols().toStringTag), ObjectPropertyDescriptor(Value(String::fromASCII("Array Iterator")), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::ConfigurablePresent))); - defineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().Array), - ObjectPropertyDescriptor(m_array, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); + redefineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().Array), + ObjectPropertyDescriptor(m_array, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); } } // namespace Escargot diff --git a/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinArrayBuffer.cpp b/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinArrayBuffer.cpp index 8216f25..409c084 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinArrayBuffer.cpp +++ b/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinArrayBuffer.cpp @@ -122,6 +122,18 @@ static Value builtinArrayBufferSlice(ExecutionState& state, Value thisValue, siz return newObject; } +void GlobalObject::initializeArrayBuffer(ExecutionState& state) +{ + ObjectPropertyNativeGetterSetterData* nativeData = new ObjectPropertyNativeGetterSetterData(true, false, true, + [](ExecutionState& state, Object* self, const Value& receiver, const EncodedValue& privateDataFromObjectPrivateArea) -> Value { + ASSERT(self->isGlobalObject()); + return self->asGlobalObject()->arrayBuffer(); + }, + nullptr); + + defineNativeDataAccessorProperty(state, ObjectPropertyName(state.context()->staticStrings().ArrayBuffer), nativeData, Value(Value::EmptyValue)); +} + void GlobalObject::installArrayBuffer(ExecutionState& state) { const StaticStrings* strings = &state.context()->staticStrings(); @@ -157,7 +169,7 @@ void GlobalObject::installArrayBuffer(ExecutionState& state) m_arrayBuffer->setFunctionPrototype(state, m_arrayBufferPrototype); - defineOwnProperty(state, ObjectPropertyName(strings->ArrayBuffer), - ObjectPropertyDescriptor(m_arrayBuffer, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); + redefineOwnProperty(state, ObjectPropertyName(strings->ArrayBuffer), + ObjectPropertyDescriptor(m_arrayBuffer, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); } } // namespace Escargot diff --git a/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinAsyncFromSyncIterator.cpp b/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinAsyncFromSyncIterator.cpp index 5a81337..04f76cf 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinAsyncFromSyncIterator.cpp +++ b/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinAsyncFromSyncIterator.cpp @@ -102,7 +102,7 @@ static Value asyncFromSyncIteratorContinuation(ExecutionState& state, Object* re static Value builtinAsyncFromSyncIteratorNext(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) { - // https://www.ecma-international.org/ecma-262/10.0/#sec-%asyncfromsynciteratorprototype%.next + // https://tc39.es/ecma262/#sec-%asyncfromsynciteratorprototype%.next // Let O be the this value. Value& O = thisValue; // Let promiseCapability be ! NewPromiseCapability(%Promise%). @@ -121,7 +121,11 @@ static Value builtinAsyncFromSyncIteratorNext(ExecutionState& state, Value thisV Object* result; try { // Let result be IteratorNext(syncIteratorRecord, value). - result = IteratorObject::iteratorNext(state, syncIteratorRecord, argv[0]); + // If value is present, then + // a. Let result be IteratorNext(syncIteratorRecord, value). + // Else, + // a. Let result be IteratorNext(syncIteratorRecord). + result = IteratorObject::iteratorNext(state, syncIteratorRecord, argc ? argv[0] : Value(Value::EmptyValue)); } catch (const Value& thrownValue) { // IfAbruptRejectPromise(result, promiseCapability). Value argv = thrownValue; @@ -134,7 +138,7 @@ static Value builtinAsyncFromSyncIteratorNext(ExecutionState& state, Value thisV static Value builtinAsyncFromSyncIteratorReturn(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) { - // https://www.ecma-international.org/ecma-262/10.0/#sec-%asyncfromsynciteratorprototype%.return + // https://tc39.es/ecma262/#sec-%asyncfromsynciteratorprototype%.return Value value = argv[0]; // Let O be the this value. Value& O = thisValue; @@ -172,10 +176,17 @@ static Value builtinAsyncFromSyncIteratorReturn(ExecutionState& state, Value thi return promiseCapability.m_promise; } - // Let result be Call(return, syncIterator, « value »). Value result; try { - result = Object::call(state, returnVariable, syncIterator, 1, &value); + // If value is present, then + // a. Let result be Call(return, syncIterator, « value »). + // Else, + // a. Let result be Call(return, syncIterator). + if (argc) { + result = Object::call(state, returnVariable, syncIterator, 1, &value); + } else { + result = Object::call(state, returnVariable, syncIterator, 0, nullptr); + } } catch (const Value& thrownValue) { // IfAbruptRejectPromise(return, promiseCapability). Value argv = thrownValue; @@ -257,8 +268,15 @@ static Value builtinAsyncFromSyncIteratorThrow(ExecutionState& state, Value this return asyncFromSyncIteratorContinuation(state, result.asObject(), promiseCapability); } +void GlobalObject::initializeAsyncFromSyncIterator(ExecutionState& state) +{ + // do nothing +} + void GlobalObject::installAsyncFromSyncIterator(ExecutionState& state) { + ASSERT(!!m_asyncIteratorPrototype); + // https://www.ecma-international.org/ecma-262/10.0/#sec-%asyncfromsynciteratorprototype%-object m_asyncFromSyncIteratorPrototype = new Object(state, m_asyncIteratorPrototype); m_asyncFromSyncIteratorPrototype->setGlobalIntrinsicObject(state, true); diff --git a/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinAsyncFunction.cpp b/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinAsyncFunction.cpp index 4835ade..041852c 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinAsyncFunction.cpp +++ b/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinAsyncFunction.cpp @@ -44,6 +44,11 @@ static Value builtinAsyncFunction(ExecutionState& state, Value thisValue, size_t return new ScriptAsyncFunctionObject(state, proto, functionSource.codeBlock, functionSource.outerEnvironment); } +void GlobalObject::initializeAsyncFunction(ExecutionState& state) +{ + // do nothing +} + void GlobalObject::installAsyncFunction(ExecutionState& state) { m_asyncFunction = new NativeFunctionObject(state, NativeFunctionInfo(state.context()->staticStrings().AsyncFunction, builtinAsyncFunction, 1), NativeFunctionObject::__ForBuiltinConstructor__); diff --git a/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinAsyncGeneratorFunction.cpp b/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinAsyncGeneratorFunction.cpp index 612e71f..1921b5a 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinAsyncGeneratorFunction.cpp +++ b/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinAsyncGeneratorFunction.cpp @@ -59,8 +59,15 @@ static Value builtinAsyncGeneratorThrow(ExecutionState& state, Value thisValue, return AsyncGeneratorObject::asyncGeneratorEnqueue(state, thisValue, AsyncGeneratorObject::AsyncGeneratorEnqueueType::Throw, argv[0]); } -void GlobalObject::installAsyncGeneratorFunction(ExecutionState& state) +void GlobalObject::initializeAsyncGenerator(ExecutionState& state) { + // do nothing +} + +void GlobalObject::installAsyncGenerator(ExecutionState& state) +{ + ASSERT(!!m_asyncIteratorPrototype); + // https://www.ecma-international.org/ecma-262/10.0/index.html#sec-asyncgeneratorfunction m_asyncGeneratorFunction = new NativeFunctionObject(state, NativeFunctionInfo(state.context()->staticStrings().AsyncGeneratorFunction, builtinAsyncGeneratorFunction, 1), NativeFunctionObject::__ForBuiltinConstructor__); m_asyncGeneratorFunction->setGlobalIntrinsicObject(state); diff --git a/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinAsyncIterator.cpp b/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinAsyncIterator.cpp deleted file mode 100644 index d58c145..0000000 --- a/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinAsyncIterator.cpp +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2020-present Samsung Electronics Co., Ltd - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - */ - -#include "Escargot.h" -#include "runtime/GlobalObject.h" -#include "runtime/Context.h" -#include "runtime/VMInstance.h" -#include "runtime/NativeFunctionObject.h" - -namespace Escargot { - -static Value builtinAsyncIteratorIterator(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - return thisValue; -} - -void GlobalObject::installAsyncIterator(ExecutionState& state) -{ - // https://www.ecma-international.org/ecma-262/10.0/index.html#sec-%iteratorprototype%-object - m_asyncIteratorPrototype = new Object(state); - m_asyncIteratorPrototype->setGlobalIntrinsicObject(state, true); - - // https://www.ecma-international.org/ecma-262/10.0/index.html#sec-asynciteratorprototype-asynciterator - m_asyncIteratorPrototype->defineOwnPropertyThrowsException(state, ObjectPropertyName(state.context()->vmInstance()->globalSymbols().asyncIterator), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(AtomicString(state, String::fromASCII("[Symbol.asyncIterator]")), builtinAsyncIteratorIterator, 0, NativeFunctionInfo::Strict)), - (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); -} -} // namespace Escargot diff --git a/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinAtomics.cpp b/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinAtomics.cpp index 7ea0d7c..4018e7e 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinAtomics.cpp +++ b/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinAtomics.cpp @@ -17,8 +17,6 @@ * USA */ -#if defined(ENABLE_THREADING) - #include "Escargot.h" #include "runtime/Context.h" #include "runtime/VMInstance.h" @@ -27,6 +25,7 @@ #include "runtime/TypedArrayInlines.h" #include "runtime/Global.h" #include "runtime/BigInt.h" +#include "runtime/Platform.h" #if !defined(HAVE_BUILTIN_ATOMIC_FUNCTIONS) && !defined(ENABLE_ATOMICS_GLOBAL_LOCK) #error "without builtin atomic functions, we need to atomics global lock for implementing atomics builtin" @@ -34,6 +33,8 @@ namespace Escargot { +#if defined(ENABLE_THREADING) + enum class AtomicBinaryOps : uint8_t { ADD, AND, @@ -242,7 +243,6 @@ static Value builtinAtomicsCompareExchange(ExecutionState& state, Value thisValu #if defined(HAVE_BUILTIN_ATOMIC_FUNCTIONS) uint8_t* replacementBytes = ALLOCA(8, uint8_t, state); TypedArrayHelper::numberToRawBytes(state, type, replacement, replacementBytes); - bool ret; switch (type) { case TypedArrayType::Int8: atomicCompareExchange(rawStart, expectedBytes, replacementBytes); @@ -315,7 +315,7 @@ static Value builtinAtomicsLoad(ExecutionState& state, Value thisValue, size_t a TypedArrayType type = TA->typedArrayType(); #if defined(HAVE_BUILTIN_ATOMIC_FUNCTIONS) - uint8_t* rawStart = TA->buffer()->data() + indexedPosition; + uint8_t* rawStart = buffer->data() + indexedPosition; uint8_t* rawBytes = ALLOCA(8, uint8_t, state); switch (type) { case TypedArrayType::Int8: @@ -383,7 +383,7 @@ static Value builtinAtomicsStore(ExecutionState& state, Value thisValue, size_t } #if defined(HAVE_BUILTIN_ATOMIC_FUNCTIONS) - uint8_t* rawStart = TA->buffer()->data() + indexedPosition; + uint8_t* rawStart = buffer->data() + indexedPosition; uint8_t* rawBytes = ALLOCA(8, uint8_t, state); TypedArrayHelper::numberToRawBytes(state, type, v, rawBytes); @@ -435,6 +435,191 @@ static Value builtinAtomicsXor(ExecutionState& state, Value thisValue, size_t ar return atomicReadModifyWrite(state, argv[0], argv[1], argv[2], AtomicBinaryOps::XOR); } +static Value builtinAtomicsWait(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) +{ + // https://tc39.es/ecma262/#sec-atomics.wait + // 25.4.12 Atomics.wait ( typedArray, index, value, timeout ) + // 1. Let buffer be ? ValidateIntegerTypedArray(typedArray, true). + ArrayBuffer* buffer = validateIntegerTypedArray(state, argv[0], true); + TypedArrayObject* typedArray = argv[0].asObject()->asTypedArrayObject(); + // 2. If IsSharedArrayBuffer(buffer) is false, throw a TypeError exception. + if (!buffer->isSharedArrayBufferObject()) { + ErrorObject::throwBuiltinError(state, ErrorObject::TypeError, "Atomics.wait expects SharedArrayBuffer"); + } + // 3. Let indexedPosition be ? ValidateAtomicAccess(typedArray, index). + size_t indexedPosition = validateAtomicAccess(state, typedArray, argv[1]); + // 4. Let arrayTypeName be typedArray.[[TypedArrayName]]. + auto arrayTypeName = typedArray->typedArrayType(); + // 5. If arrayTypeName is "BigInt64Array", let v be ? ToBigInt64(value). + Value v; + if (arrayTypeName == TypedArrayType::BigInt64) { + v = argv[2].toBigInt(state); + } else { + // 6. Otherwise, let v be ? ToInt32(value). + v = Value(argv[2].toInt32(state)); + } + // 7. Let q be ? ToNumber(timeout). + double q = argv[3].toNumber(state); + // 8. If q is NaN or +∞𝔽, let t be +∞; else if q is -∞𝔽, let t be 0; else let t be max(ℝ(q), 0). + double t; + if (std::isnan(q) || q == std::numeric_limits::infinity()) { + t = std::numeric_limits::infinity(); + } else if (q == -std::numeric_limits::infinity()) { + t = 0; + } else { + t = std::max(q, 0.0); + } + // 9. Let B be AgentCanSuspend(). + // 10. If B is false, throw a TypeError exception. + if (!Global::platform()->canBlockExecution(state.context())) { + ErrorObject::throwBuiltinError(state, ErrorObject::TypeError, "Cannot suspend this thread"); + } + // 11. Let block be buffer.[[ArrayBufferData]]. + void* blockAddress = reinterpret_cast(buffer->data()) + indexedPosition; + // 12. Let WL be GetWaiterList(block, indexedPosition). + Global::Waiter* WL = Global::waiter(blockAddress); + // 13. Perform EnterCriticalSection(WL). + WL->m_mutex.lock(); + // 14. Let elementType be the Element Type value in Table 63 for arrayTypeName. + // 15. Let w be ! GetValueFromBuffer(buffer, indexedPosition, elementType, true, SeqCst). + Value w(Value::ForceUninitialized); +#if defined(HAVE_BUILTIN_ATOMIC_FUNCTIONS) + uint8_t* rawStart = buffer->data() + indexedPosition; + uint8_t* rawBytes = ALLOCA(8, uint8_t, state); + switch (arrayTypeName) { + case TypedArrayType::Int32: + atomicLoad(rawStart, rawBytes); + break; + case TypedArrayType::BigInt64: + atomicLoad(rawStart, rawBytes); + break; + default: + RELEASE_ASSERT_NOT_REACHED(); + break; + } + w = TypedArrayHelper::rawBytesToNumber(state, arrayTypeName, rawBytes); +#else + { + std::lock_guard guard(Global::atomicsLock()); + w = buffer->getValueFromBuffer(state, indexedPosition, arrayTypeName); + } +#endif + // 16. If v ≠ w, then + if (!v.equalsTo(state, w)) { + // a. Perform LeaveCriticalSection(WL). + WL->m_mutex.unlock(); + // b. Return the String "not-equal". + return Value(state.context()->staticStrings().lazyNotEqual().string()); + } + // 17. Let W be AgentSignifier(). + // 18. Perform AddWaiter(WL, W). + // 19. Let notified be SuspendAgent(WL, W, t). + bool notified = true; + std::unique_lock ul(WL->m_conditionVariableMutex); + WL->m_waiterCount++; + WL->m_mutex.unlock(); + if (t == std::numeric_limits::infinity()) { + WL->m_waiter.wait(ul); + } else { + notified = WL->m_waiter.wait_for(ul, std::chrono::milliseconds((int64_t)t)) == std::cv_status::no_timeout; + } + WL->m_mutex.lock(); + // 20. If notified is true, then + // a. Assert: W is not on the list of waiters in WL. + // 21. Else, + // a. Perform RemoveWaiter(WL, W). + if (!notified) { + WL->m_waiterCount--; + } + // 22. Perform LeaveCriticalSection(WL). + WL->m_mutex.unlock(); + // 23. If notified is true, return the String "ok". + if (notified) { + return Value(state.context()->staticStrings().lazyOk().string()); + } + // 24. Return the String "timed-out". + return Value(state.context()->staticStrings().lazyTimedOut().string()); +} + +static Value builtinAtomicsNotify(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) +{ + // https://tc39.es/ecma262/#sec-atomics.notify + // Atomics.notify ( typedArray, index, count ) + // 1. Let buffer be ? ValidateIntegerTypedArray(typedArray, true). + ArrayBuffer* buffer = validateIntegerTypedArray(state, argv[0], true); + TypedArrayObject* typedArray = argv[0].asObject()->asTypedArrayObject(); + // 2. Let indexedPosition be ? ValidateAtomicAccess(typedArray, index). + size_t indexedPosition = validateAtomicAccess(state, typedArray, argv[1]); + double c; + // 3. If count is undefined, let c be +∞. + if (argv[2].isUndefined()) { + c = std::numeric_limits::infinity(); + } else { + // 4. Else, + // a. Let intCount be ? ToIntegerOrInfinity(count). + auto intCount = argv[2].toInteger(state); + // b. Let c be max(intCount, 0). + c = std::max(intCount, 0.0); + } + // 5. Let block be buffer.[[ArrayBufferData]]. + void* blockAddress = reinterpret_cast(buffer->data()) + indexedPosition; + // 6. Let arrayTypeName be typedArray.[[TypedArrayName]]. + // 7. If IsSharedArrayBuffer(buffer) is false, return +0𝔽. + if (!buffer->isSharedArrayBufferObject()) { + return Value(0); + } + // 8. Let WL be GetWaiterList(block, indexedPosition). + Global::Waiter* WL = Global::waiter(blockAddress); + // 9. Let n be 0. + double n = 0; + // 10. Perform EnterCriticalSection(WL). + WL->m_mutex.lock(); + double count = std::min((double)WL->m_waiterCount, c); + WL->m_waiterCount -= count; + // 11. Let S be RemoveWaiters(WL, c). + // 12. Repeat, while S is not an empty List, + // a. Let W be the first agent in S. + // b. Remove W from the front of S. + // c. Perform NotifyWaiter(WL, W). + // d. Set n to n + 1. + for (n = 0; n < count; n++) { + WL->m_mutex.unlock(); + WL->m_waiter.notify_one(); + WL->m_mutex.lock(); + } + // 13. Perform LeaveCriticalSection(WL). + WL->m_mutex.unlock(); + // 14. Return 𝔽(n). + return Value(n); +} + +static Value builtinAtomicsIsLockFree(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) +{ + auto size = argv[0].toInteger(state); +#if defined(HAVE_BUILTIN_ATOMIC_FUNCTIONS) + if (size == 1 || size == 2 || size == 4 || size == 8) { + return Value(true); + } + return Value(false); +#else + // spec want to do toInteger operation + size; + return Value(false); +#endif +} + +void GlobalObject::initializeAtomics(ExecutionState& state) +{ + ObjectPropertyNativeGetterSetterData* nativeData = new ObjectPropertyNativeGetterSetterData(true, false, true, + [](ExecutionState& state, Object* self, const Value& receiver, const EncodedValue& privateDataFromObjectPrivateArea) -> Value { + ASSERT(self->isGlobalObject()); + return self->asGlobalObject()->atomics(); + }, + nullptr); + + defineNativeDataAccessorProperty(state, ObjectPropertyName(state.context()->staticStrings().Atomics), nativeData, Value(Value::EmptyValue)); +} + void GlobalObject::installAtomics(ExecutionState& state) { m_atomics = new Object(state); @@ -470,9 +655,24 @@ void GlobalObject::installAtomics(ExecutionState& state) m_atomics->defineOwnPropertyThrowsException(state, ObjectPropertyName(state.context()->staticStrings().stringXor), ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(state.context()->staticStrings().stringXor, builtinAtomicsXor, 3, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - defineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().Atomics), - ObjectPropertyDescriptor(m_atomics, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); + m_atomics->defineOwnPropertyThrowsException(state, ObjectPropertyName(state.context()->staticStrings().isLockFree), + ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(state.context()->staticStrings().isLockFree, builtinAtomicsIsLockFree, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); + + m_atomics->defineOwnPropertyThrowsException(state, ObjectPropertyName(state.context()->staticStrings().wait), + ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(state.context()->staticStrings().wait, builtinAtomicsWait, 4, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); + + m_atomics->defineOwnPropertyThrowsException(state, ObjectPropertyName(state.context()->staticStrings().notify), + ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(state.context()->staticStrings().notify, builtinAtomicsNotify, 3, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); + + redefineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().Atomics), + ObjectPropertyDescriptor(m_atomics, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); +} +#else + +void GlobalObject::initializeAtomics(ExecutionState& state) +{ + // dummy initialize function } -} // namespace Escargot #endif +} // namespace Escargot diff --git a/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinBigInt.cpp b/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinBigInt.cpp index c0a27e4..73ac0e6 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinBigInt.cpp +++ b/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinBigInt.cpp @@ -186,6 +186,18 @@ static Value builtinBigIntToLocaleString(ExecutionState& state, Value thisValue, #endif } +void GlobalObject::initializeBigInt(ExecutionState& state) +{ + ObjectPropertyNativeGetterSetterData* nativeData = new ObjectPropertyNativeGetterSetterData(true, false, true, + [](ExecutionState& state, Object* self, const Value& receiver, const EncodedValue& privateDataFromObjectPrivateArea) -> Value { + ASSERT(self->isGlobalObject()); + return self->asGlobalObject()->bigInt(); + }, + nullptr); + + defineNativeDataAccessorProperty(state, ObjectPropertyName(state.context()->staticStrings().BigInt), nativeData, Value(Value::EmptyValue)); +} + void GlobalObject::installBigInt(ExecutionState& state) { m_bigInt = new NativeFunctionObject(state, NativeFunctionInfo(state.context()->staticStrings().BigInt, builtinBigIntConstructor, 1), NativeFunctionObject::__ForBuiltinConstructor__); @@ -221,7 +233,10 @@ void GlobalObject::installBigInt(ExecutionState& state) m_bigInt->setFunctionPrototype(state, m_bigIntPrototype); - defineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().BigInt), - ObjectPropertyDescriptor(m_bigInt, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); + + m_bigIntProxyObject = new BigIntObject(state, new BigInt(UINT64_C(0))); + + redefineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().BigInt), + ObjectPropertyDescriptor(m_bigInt, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); } } // namespace Escargot diff --git a/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinBoolean.cpp b/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinBoolean.cpp index 1a07a2f..56560a3 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinBoolean.cpp +++ b/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinBoolean.cpp @@ -61,6 +61,18 @@ static Value builtinBooleanToString(ExecutionState& state, Value thisValue, size RELEASE_ASSERT_NOT_REACHED(); } +void GlobalObject::initializeBoolean(ExecutionState& state) +{ + ObjectPropertyNativeGetterSetterData* nativeData = new ObjectPropertyNativeGetterSetterData(true, false, true, + [](ExecutionState& state, Object* self, const Value& receiver, const EncodedValue& privateDataFromObjectPrivateArea) -> Value { + ASSERT(self->isGlobalObject()); + return self->asGlobalObject()->boolean(); + }, + nullptr); + + defineNativeDataAccessorProperty(state, ObjectPropertyName(state.context()->staticStrings().Boolean), nativeData, Value(Value::EmptyValue)); +} + void GlobalObject::installBoolean(ExecutionState& state) { const StaticStrings* strings = &state.context()->staticStrings(); @@ -82,7 +94,9 @@ void GlobalObject::installBoolean(ExecutionState& state) m_boolean->setFunctionPrototype(state, m_booleanPrototype); - defineOwnProperty(state, ObjectPropertyName(strings->Boolean), - ObjectPropertyDescriptor(m_boolean, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); + m_booleanProxyObject = new BooleanObject(state); + + redefineOwnProperty(state, ObjectPropertyName(strings->Boolean), + ObjectPropertyDescriptor(m_boolean, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); } } // namespace Escargot diff --git a/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinDataView.cpp b/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinDataView.cpp index 5ca74af..5d9e1e5 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinDataView.cpp +++ b/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinDataView.cpp @@ -154,6 +154,18 @@ static Value builtinDataViewByteOffsetGetter(ExecutionState& state, Value thisVa RELEASE_ASSERT_NOT_REACHED(); } +void GlobalObject::initializeDataView(ExecutionState& state) +{ + ObjectPropertyNativeGetterSetterData* nativeData = new ObjectPropertyNativeGetterSetterData(true, false, true, + [](ExecutionState& state, Object* self, const Value& receiver, const EncodedValue& privateDataFromObjectPrivateArea) -> Value { + ASSERT(self->isGlobalObject()); + return self->asGlobalObject()->dataView(); + }, + nullptr); + + defineNativeDataAccessorProperty(state, ObjectPropertyName(state.context()->staticStrings().DataView), nativeData, Value(Value::EmptyValue)); +} + void GlobalObject::installDataView(ExecutionState& state) { m_dataView = new NativeFunctionObject(state, NativeFunctionInfo(state.context()->staticStrings().DataView, builtinDataViewConstructor, 1), NativeFunctionObject::__ForBuiltinConstructor__); @@ -205,7 +217,7 @@ void GlobalObject::installDataView(ExecutionState& state) m_dataViewPrototype->defineOwnProperty(state, ObjectPropertyName(strings->byteOffset), byteOffsetDesc); } - defineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().DataView), - ObjectPropertyDescriptor(m_dataView, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); + redefineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().DataView), + ObjectPropertyDescriptor(m_dataView, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); } } // namespace Escargot diff --git a/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinDate.cpp b/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinDate.cpp index 6ccfc5f..dc89198 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinDate.cpp +++ b/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinDate.cpp @@ -216,21 +216,21 @@ static Value builtinDateToTimeString(ExecutionState& state, Value thisValue, siz } #if defined(ENABLE_ICU) && defined(ENABLE_INTL) -#define INTL_DATE_TIME_FORMAT_FORMAT(REQUIRED, DEFUALT) \ - double x = thisObject->primitiveValue(); \ - if (std::isnan(x)) { \ - return new ASCIIString("Invalid Date"); \ - } \ - Value locales, options; \ - if (argc >= 1) { \ - locales = argv[0]; \ - } \ - if (argc >= 2) { \ - options = argv[1]; \ - } \ - auto dateTimeOption = IntlDateTimeFormat::toDateTimeOptions(state, options, String::fromASCII(REQUIRED), String::fromASCII(DEFUALT)); \ - Object* dateFormat = IntlDateTimeFormat::create(state, state.context(), locales, dateTimeOption); \ - auto result = IntlDateTimeFormat::format(state, dateFormat, x); \ +#define INTL_DATE_TIME_FORMAT_FORMAT(REQUIRED, DEFUALT) \ + double x = thisObject->primitiveValue(); \ + if (std::isnan(x)) { \ + return new ASCIIString("Invalid Date"); \ + } \ + Value locales, options; \ + if (argc >= 1) { \ + locales = argv[0]; \ + } \ + if (argc >= 2) { \ + options = argv[1]; \ + } \ + auto dateTimeOption = IntlDateTimeFormatObject::toDateTimeOptions(state, options, String::fromASCII(REQUIRED), String::fromASCII(DEFUALT)); \ + IntlDateTimeFormatObject* dateFormat = new IntlDateTimeFormatObject(state, locales, dateTimeOption); \ + auto result = dateFormat->format(state, x); \ return new UTF16String(result.data(), result.length()); #endif @@ -505,6 +505,18 @@ static Value builtinDateToPrimitive(ExecutionState& state, Value thisValue, size } } +void GlobalObject::initializeDate(ExecutionState& state) +{ + ObjectPropertyNativeGetterSetterData* nativeData = new ObjectPropertyNativeGetterSetterData(true, false, true, + [](ExecutionState& state, Object* self, const Value& receiver, const EncodedValue& privateDataFromObjectPrivateArea) -> Value { + ASSERT(self->isGlobalObject()); + return self->asGlobalObject()->date(); + }, + nullptr); + + defineNativeDataAccessorProperty(state, ObjectPropertyName(state.context()->staticStrings().Date), nativeData, Value(Value::EmptyValue)); +} + void GlobalObject::installDate(ExecutionState& state) { m_date = new NativeFunctionObject(state, NativeFunctionInfo(state.context()->staticStrings().Date, builtinDateConstructor, 7), NativeFunctionObject::__ForBuiltinConstructor__); @@ -593,7 +605,7 @@ void GlobalObject::installDate(ExecutionState& state) m_date->setFunctionPrototype(state, m_datePrototype); - defineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().Date), - ObjectPropertyDescriptor(m_date, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); + redefineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().Date), + ObjectPropertyDescriptor(m_date, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); } } // namespace Escargot diff --git a/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinError.cpp b/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinError.cpp index e0bd9c6..3558c7c 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinError.cpp +++ b/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinError.cpp @@ -26,6 +26,22 @@ namespace Escargot { +static void installErrorCause(ExecutionState& state, Object* obj, const Value& options) +{ + const AtomicString& causeString = state.context()->staticStrings().cause; + // 1. If Type(options) is Object and ? HasProperty(options, "cause") is true, then + if (options.isObject()) { + auto res = options.asObject()->hasProperty(state, ObjectPropertyName(causeString)); + if (res) { + // Let cause be ? Get(options, "cause"). + Value cause = res.value(state, ObjectPropertyName(causeString), options); + // Perform ! CreateNonEnumerableDataPropertyOrThrow(O, "cause", cause). + obj->defineOwnPropertyThrowsException(state, causeString, + ObjectPropertyDescriptor(cause, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectStructurePropertyDescriptor::ConfigurablePresent))); + } + } +} + static Value builtinErrorConstructor(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) { if (!newTarget.hasValue()) { @@ -39,28 +55,33 @@ static Value builtinErrorConstructor(ExecutionState& state, Value thisValue, siz Value message = argv[0]; if (!message.isUndefined()) { - obj->defineOwnPropertyThrowsExceptionWhenStrictMode(state, state.context()->staticStrings().message, - ObjectPropertyDescriptor(message.toString(state), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectStructurePropertyDescriptor::ConfigurablePresent))); + obj->defineOwnPropertyThrowsException(state, state.context()->staticStrings().message, + ObjectPropertyDescriptor(message.toString(state), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectStructurePropertyDescriptor::ConfigurablePresent))); } + + Value options = argc > 1 ? argv[1] : Value(); + installErrorCause(state, obj, options); return obj; } -#define DEFINE_ERROR_CTOR(errorName, lowerCaseErrorName) \ - static Value builtin##errorName##ErrorConstructor(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) \ - { \ - if (!newTarget.hasValue()) { \ - newTarget = state.resolveCallee(); \ - } \ - Object* proto = Object::getPrototypeFromConstructor(state, newTarget.value(), [](ExecutionState& state, Context* constructorRealm) -> Object* { \ - return constructorRealm->globalObject()->lowerCaseErrorName##ErrorPrototype(); \ - }); \ - ErrorObject* obj = new errorName##ErrorObject(state, proto, String::emptyString); \ - Value message = argv[0]; \ - if (!message.isUndefined()) { \ - obj->defineOwnPropertyThrowsExceptionWhenStrictMode(state, state.context()->staticStrings().message, \ - ObjectPropertyDescriptor(message.toString(state), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectStructurePropertyDescriptor::ConfigurablePresent))); \ - } \ - return obj; \ +#define DEFINE_ERROR_CTOR(errorName, lowerCaseErrorName) \ + static Value builtin##errorName##ErrorConstructor(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) \ + { \ + if (!newTarget.hasValue()) { \ + newTarget = state.resolveCallee(); \ + } \ + Object* proto = Object::getPrototypeFromConstructor(state, newTarget.value(), [](ExecutionState& state, Context* constructorRealm) -> Object* { \ + return constructorRealm->globalObject()->lowerCaseErrorName##ErrorPrototype(); \ + }); \ + ErrorObject* obj = new errorName##ErrorObject(state, proto, String::emptyString); \ + Value message = argv[0]; \ + if (!message.isUndefined()) { \ + obj->defineOwnPropertyThrowsException(state, state.context()->staticStrings().message, \ + ObjectPropertyDescriptor(message.toString(state), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectStructurePropertyDescriptor::ConfigurablePresent))); \ + } \ + Value options = argc > 1 ? argv[1] : Value(); \ + installErrorCause(state, obj, options); \ + return obj; \ } DEFINE_ERROR_CTOR(Reference, reference); @@ -87,15 +108,19 @@ static Value builtinAggregateErrorConstructor(ExecutionState& state, Value thisV // Let msg be ? ToString(message). // Let msgDesc be the PropertyDescriptor { [[Value]]: msg, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }. // Perform ! DefinePropertyOrThrow(O, "message", msgDesc). - O->defineOwnPropertyThrowsExceptionWhenStrictMode(state, state.context()->staticStrings().message, - ObjectPropertyDescriptor(message.toString(state), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectStructurePropertyDescriptor::ConfigurablePresent))); + O->defineOwnPropertyThrowsException(state, state.context()->staticStrings().message, + ObjectPropertyDescriptor(message.toString(state), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectStructurePropertyDescriptor::ConfigurablePresent))); } + // Perform ? InstallErrorCause(O, options). + Value options = argc > 2 ? argv[2] : Value(); + installErrorCause(state, O, options); + // Let errorsList be ? IterableToList(errors). auto errorsList = IteratorObject::iterableToList(state, argv[0]); // Perform ! DefinePropertyOrThrow(O, "errors", PropertyDescriptor { [[Configurable]]: true, [[Enumerable]]: false, [[Writable]]: true, [[Value]]: ! CreateArrayFromList(errorsList) }). - O->defineOwnPropertyThrowsExceptionWhenStrictMode(state, ObjectPropertyName(state, String::fromASCII("errors")), - ObjectPropertyDescriptor(Value(Object::createArrayFromList(state, errorsList.size(), errorsList.data())), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectStructurePropertyDescriptor::ConfigurablePresent))); + O->defineOwnPropertyThrowsException(state, ObjectPropertyName(state, String::fromASCII("errors")), + ObjectPropertyDescriptor(Value(Object::createArrayFromList(state, errorsList.size(), errorsList.data())), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectStructurePropertyDescriptor::ConfigurablePresent))); // Return O. return O; } @@ -148,6 +173,38 @@ static Value builtinErrorToString(ExecutionState& state, Value thisValue, size_t return builder.finalize(&state); } +void GlobalObject::initializeError(ExecutionState& state) +{ +#define DEFINE_ERROR_INIT(errorname, bname) \ + { \ + ObjectPropertyNativeGetterSetterData* nativeData = new ObjectPropertyNativeGetterSetterData(true, false, true, \ + [](ExecutionState& state, Object* self, const Value& receiver, const EncodedValue& privateDataFromObjectPrivateArea) -> Value { \ + ASSERT(self->isGlobalObject()); \ + return self->asGlobalObject()->errorname##Error(); \ + }, \ + nullptr); \ + defineNativeDataAccessorProperty(state, ObjectPropertyName(state.context()->staticStrings().bname##Error), nativeData, Value(Value::EmptyValue)); \ + } + + DEFINE_ERROR_INIT(reference, Reference); + DEFINE_ERROR_INIT(type, Type); + DEFINE_ERROR_INIT(syntax, Syntax); + DEFINE_ERROR_INIT(range, Range); + DEFINE_ERROR_INIT(uri, URI); + DEFINE_ERROR_INIT(eval, Eval); + DEFINE_ERROR_INIT(aggregate, Aggregate); + + { + ObjectPropertyNativeGetterSetterData* nativeData = new ObjectPropertyNativeGetterSetterData(true, false, true, + [](ExecutionState& state, Object* self, const Value& receiver, const EncodedValue& privateDataFromObjectPrivateArea) -> Value { + ASSERT(self->isGlobalObject()); + return self->asGlobalObject()->error(); + }, + nullptr); + defineNativeDataAccessorProperty(state, ObjectPropertyName(state.context()->staticStrings().Error), nativeData, Value(Value::EmptyValue)); + } +} + void GlobalObject::installError(ExecutionState& state) { m_error = new NativeFunctionObject(state, NativeFunctionInfo(state.context()->staticStrings().Error, builtinErrorConstructor, 1), NativeFunctionObject::__ForBuiltinConstructor__); @@ -187,8 +244,8 @@ void GlobalObject::installError(ExecutionState& state) m_##errorname##ErrorPrototype->defineOwnProperty(state, state.context()->staticStrings().message, ObjectPropertyDescriptor(String::emptyString, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectStructurePropertyDescriptor::ConfigurablePresent))); \ m_##errorname##ErrorPrototype->defineOwnProperty(state, state.context()->staticStrings().name, ObjectPropertyDescriptor(state.context()->staticStrings().bname##Error.string(), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectStructurePropertyDescriptor::ConfigurablePresent))); \ m_##errorname##Error->setFunctionPrototype(state, m_##errorname##ErrorPrototype); \ - defineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().bname##Error), \ - ObjectPropertyDescriptor(m_##errorname##Error, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectStructurePropertyDescriptor::ConfigurablePresent))); + redefineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().bname##Error), \ + ObjectPropertyDescriptor(m_##errorname##Error, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectStructurePropertyDescriptor::ConfigurablePresent))); DEFINE_ERROR(reference, Reference, 1); DEFINE_ERROR(type, Type, 1); @@ -198,7 +255,7 @@ void GlobalObject::installError(ExecutionState& state) DEFINE_ERROR(eval, Eval, 1); DEFINE_ERROR(aggregate, Aggregate, 2); - defineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().Error), - ObjectPropertyDescriptor(m_error, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); + redefineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().Error), + ObjectPropertyDescriptor(m_error, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); } } // namespace Escargot diff --git a/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinFinalizationRegistry.cpp b/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinFinalizationRegistry.cpp index e2ca14c..312691f 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinFinalizationRegistry.cpp +++ b/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinFinalizationRegistry.cpp @@ -99,6 +99,18 @@ static Value builtinfinalizationRegistryCleanupSome(ExecutionState& state, Value return Value(); } +void GlobalObject::initializeFinalizationRegistry(ExecutionState& state) +{ + ObjectPropertyNativeGetterSetterData* nativeData = new ObjectPropertyNativeGetterSetterData(true, false, true, + [](ExecutionState& state, Object* self, const Value& receiver, const EncodedValue& privateDataFromObjectPrivateArea) -> Value { + ASSERT(self->isGlobalObject()); + return self->asGlobalObject()->finalizationRegistry(); + }, + nullptr); + + defineNativeDataAccessorProperty(state, ObjectPropertyName(state.context()->staticStrings().FinalizationRegistry), nativeData, Value(Value::EmptyValue)); +} + void GlobalObject::installFinalizationRegistry(ExecutionState& state) { m_finalizationRegistry = new NativeFunctionObject(state, NativeFunctionInfo(state.context()->staticStrings().FinalizationRegistry, builtinFinalizationRegistryConstructor, 1), NativeFunctionObject::__ForBuiltinConstructor__); @@ -125,7 +137,7 @@ void GlobalObject::installFinalizationRegistry(ExecutionState& state) ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(state.context()->staticStrings().cleanupSome, builtinfinalizationRegistryCleanupSome, 0, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); m_finalizationRegistry->setFunctionPrototype(state, m_finalizationRegistryPrototype); - defineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().FinalizationRegistry), - ObjectPropertyDescriptor(m_finalizationRegistry, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent | ObjectPropertyDescriptor::NonEnumerablePresent))); + redefineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().FinalizationRegistry), + ObjectPropertyDescriptor(m_finalizationRegistry, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent | ObjectPropertyDescriptor::NonEnumerablePresent))); } } // namespace Escargot diff --git a/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinFunction.cpp b/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinFunction.cpp index 197cb7f..d5761b6 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinFunction.cpp +++ b/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinFunction.cpp @@ -203,6 +203,80 @@ static Value builtinFunctionHasInstanceOf(ExecutionState& state, Value thisValue return Value(thisValue.asObject()->hasInstance(state, argv[0])); } +static Value builtinCallerAndArgumentsGetterSetter(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) +{ + FunctionObject* targetFunction = nullptr; + bool needThrow = false; + if (thisValue.isCallable()) { + if (thisValue.isFunction()) { + targetFunction = thisValue.asFunction(); + if (targetFunction->isScriptFunctionObject()) { + InterpretedCodeBlock* codeBlock = targetFunction->asScriptFunctionObject()->interpretedCodeBlock(); + if (codeBlock->isStrict() || codeBlock->isArrowFunctionExpression() || codeBlock->isGenerator()) { + needThrow = true; + } + } else { + ASSERT(targetFunction->isNativeFunctionObject()); + if (targetFunction->asNativeFunctionObject()->nativeCodeBlock()->isStrict()) { + needThrow = true; + } + } + } else if (thisValue.isObject()) { + auto object = thisValue.asObject(); + if (object->isBoundFunctionObject()) { + needThrow = true; + } + } + } else if (!thisValue.isPrimitive() && !thisValue.isObject()) { + needThrow = true; + } + + if (needThrow) { + ErrorObject::throwBuiltinError(state, ErrorObject::TypeError, "'caller' and 'arguments' restrict properties may not be accessed on strict mode functions or the arguments objects for calls to them"); + } + + bool inStrict = false; + + ExecutionState* p = state.parent(); + while (p) { + if (p->inStrictMode()) { + inStrict = true; + break; + } + p = p->parent(); + } + + if (targetFunction && !inStrict) { + bool foundTargetFunction = false; + ExecutionState* p = &state; + while (p) { + if (foundTargetFunction) { + auto callee = p->resolveCallee(); + if (callee != targetFunction) { + if (callee) { + return Value(callee); + } else { + return Value(Value::Null); + } + } + } else { + if (p->resolveCallee() == targetFunction) { + foundTargetFunction = true; + } + } + p = p->parent(); + } + } + + return Value(Value::Null); +} + +void GlobalObject::initializeFunction(ExecutionState& state) +{ + // Function should be installed at the start time + installFunction(state); +} + void GlobalObject::installFunction(ExecutionState& state) { m_functionPrototype = new NativeFunctionObject(state, NativeFunctionInfo(AtomicString(), builtinFunctionEmptyFunction, 0, NativeFunctionInfo::Strict), @@ -232,6 +306,18 @@ void GlobalObject::installFunction(ExecutionState& state) m_functionPrototype->defineOwnPropertyThrowsException(state, ObjectPropertyName(state, Value(state.context()->vmInstance()->globalSymbols().hasInstance)), ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(AtomicString(state, String::fromASCII("[Symbol.hasInstance]")), builtinFunctionHasInstanceOf, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::NonWritablePresent | ObjectPropertyDescriptor::NonConfigurablePresent))); + // 8.2.2 - 12 + // AddRestrictedFunctionProperties(funcProto, realmRec). + m_callerAndArgumentsGetterSetter = new NativeFunctionObject(state, NativeFunctionInfo(state.context()->staticStrings().caller, builtinCallerAndArgumentsGetterSetter, 0, NativeFunctionInfo::Strict)); + + { + JSGetterSetter gs(m_callerAndArgumentsGetterSetter, m_callerAndArgumentsGetterSetter); + ObjectPropertyDescriptor desc(gs, ObjectPropertyDescriptor::ConfigurablePresent); + + m_functionPrototype->defineOwnPropertyThrowsException(state, ObjectPropertyName(state.context()->staticStrings().caller), desc); + m_functionPrototype->defineOwnPropertyThrowsException(state, ObjectPropertyName(state.context()->staticStrings().arguments), desc); + } + defineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().Function), ObjectPropertyDescriptor(m_function, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); } diff --git a/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinGeneratorFunction.cpp b/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinGeneratorFunction.cpp index 3014125..8f2dc53 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinGeneratorFunction.cpp +++ b/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinGeneratorFunction.cpp @@ -59,8 +59,15 @@ static Value builtinGeneratorThrow(ExecutionState& state, Value thisValue, size_ return GeneratorObject::generatorResumeAbrupt(state, thisValue, argc > 0 ? argv[0] : Value(), GeneratorObject::GeneratorAbruptType::Throw); } +void GlobalObject::initializeGenerator(ExecutionState& state) +{ + // do nothing +} + void GlobalObject::installGenerator(ExecutionState& state) { + ASSERT(!!m_iteratorPrototype); + // %GeneratorFunction% : The constructor of generator objects m_generatorFunction = new NativeFunctionObject(state, NativeFunctionInfo(state.context()->staticStrings().GeneratorFunction, builtinGeneratorFunction, 1), NativeFunctionObject::__ForBuiltinConstructor__); m_generatorFunction->setGlobalIntrinsicObject(state); @@ -70,10 +77,18 @@ void GlobalObject::installGenerator(ExecutionState& state) m_generator->setGlobalIntrinsicObject(state, true); m_generatorFunction->setFunctionPrototype(state, m_generator); - // 25.2.3.1 The initial value of GeneratorFunction.prototype.constructor is the intrinsic object %GeneratorFunction%. m_generator->defineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().constructor), ObjectPropertyDescriptor(m_generatorFunction, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::NonWritablePresent | ObjectPropertyDescriptor::NonEnumerablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); + { + ASSERT(!!m_callerAndArgumentsGetterSetter); + JSGetterSetter gs(m_callerAndArgumentsGetterSetter, m_callerAndArgumentsGetterSetter); + ObjectPropertyDescriptor desc(gs, ObjectPropertyDescriptor::ConfigurablePresent); + + m_generator->defineOwnPropertyThrowsException(state, ObjectPropertyName(state.context()->staticStrings().caller), desc); + m_generator->defineOwnPropertyThrowsException(state, ObjectPropertyName(state.context()->staticStrings().arguments), desc); + } + // %GeneratorPrototype% : The initial value of the prototype property of %Generator% m_generatorPrototype = new Object(state, m_iteratorPrototype); m_generatorPrototype->setGlobalIntrinsicObject(state, true); diff --git a/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinIntl.cpp b/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinIntl.cpp index cfa9c67..e114ca7 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinIntl.cpp +++ b/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinIntl.cpp @@ -1,4 +1,3 @@ -#if defined(ENABLE_ICU) && defined(ENABLE_INTL) /* * Copyright (C) 2015 Andy VanWagoner (thetalecrafter@gmail.com) * Copyright (C) 2015 Sukolsak Sakshuwong (sukolsak@gmail.com) @@ -62,6 +61,8 @@ namespace Escargot { +#if defined(ENABLE_ICU) && defined(ENABLE_INTL) + static Value builtinIntlCollatorConstructor(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) { // https://www.ecma-international.org/ecma-402/6.0/index.html#sec-intl.collator @@ -181,48 +182,44 @@ static Value builtinIntlDateTimeFormatConstructor(ExecutionState& state, Value t Object* proto = Object::getPrototypeFromConstructor(state, newTargetVariable, [](ExecutionState& state, Context* realm) -> Object* { return realm->globalObject()->intlDateTimeFormatPrototype(); }); - Object* dateTimeFormat = new Object(state, proto); - IntlDateTimeFormat::initialize(state, dateTimeFormat, locales, options); + Object* dateTimeFormat = new IntlDateTimeFormatObject(state, proto, locales, options); return dateTimeFormat; } static Value builtinIntlDateTimeFormatFormat(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) { FunctionObject* callee = state.resolveCallee(); - if (!callee->hasInternalSlot() || !callee->internalSlot()->hasOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().lazyInitializedDateTimeFormat()))) { + if (!callee->internalSlot() || !callee->internalSlot()->isIntlDateTimeFormatObject()) { ErrorObject::throwBuiltinError(state, ErrorObject::TypeError, "Method called on incompatible receiver"); } - Object* dateTimeFormat = callee->asObject(); + IntlDateTimeFormatObject* dateTimeFormat = callee->internalSlot()->asIntlDateTimeFormatObject(); double value; if (argc == 0 || argv[0].isUndefined()) { value = DateObject::currentTime(); } else { value = argv[0].toNumber(state); } - auto result = IntlDateTimeFormat::format(state, dateTimeFormat, value); + auto result = dateTimeFormat->format(state, value); return Value(new UTF16String(result.data(), result.length())); } static Value builtinIntlDateTimeFormatFormatGetter(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) { - if (!thisValue.isObject() || !thisValue.asObject()->hasInternalSlot() || !thisValue.asObject()->internalSlot()->hasOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().lazyInitializedDateTimeFormat()))) { + if (!thisValue.isObject() || !thisValue.asObject()->isIntlDateTimeFormatObject()) { ErrorObject::throwBuiltinError(state, ErrorObject::TypeError, "Method called on incompatible receiver"); } - Object* internalSlot = thisValue.asObject()->internalSlot(); - FunctionObject* fn; - auto g = internalSlot->get(state, ObjectPropertyName(state.context()->staticStrings().format)); - if (g.hasValue()) { - fn = g.value(state, internalSlot).asFunction(); - } else { - fn = new NativeFunctionObject(state, NativeFunctionInfo(AtomicString(), builtinIntlDateTimeFormatFormat, 1, NativeFunctionInfo::Strict)); - internalSlot->set(state, ObjectPropertyName(state.context()->staticStrings().format), Value(fn), internalSlot); - fn->setInternalSlot(internalSlot); + IntlDateTimeFormatObject* dtf = thisValue.asObject()->asIntlDateTimeFormatObject(); + + if (!dtf->internalSlot()) { + FunctionObject* formatFunction = new NativeFunctionObject(state, NativeFunctionInfo(AtomicString(), builtinIntlDateTimeFormatFormat, 1, NativeFunctionInfo::Strict)); + formatFunction->setInternalSlot(dtf); + dtf->setInternalSlot(formatFunction); } - return fn; + return dtf->internalSlot(); } static Value builtinIntlDateTimeFormatFormatToParts(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) @@ -230,9 +227,10 @@ static Value builtinIntlDateTimeFormatFormatToParts(ExecutionState& state, Value // Let dtf be this value. // If Type(dtf) is not Object, throw a TypeError exception. // If dtf does not have an [[InitializedDateTimeFormat]] internal slot, throw a TypeError exception. - if (!thisValue.isObject() || !thisValue.asObject()->hasInternalSlot() || !thisValue.asObject()->internalSlot()->hasOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().lazyInitializedDateTimeFormat()))) { + if (!thisValue.isObject() || !thisValue.asObject()->isIntlDateTimeFormatObject()) { ErrorObject::throwBuiltinError(state, ErrorObject::TypeError, "Method called on incompatible receiver"); } + IntlDateTimeFormatObject* dtf = thisValue.asObject()->asIntlDateTimeFormatObject(); Value date = argv[0]; double x; // If date is undefined, then @@ -245,7 +243,7 @@ static Value builtinIntlDateTimeFormatFormatToParts(ExecutionState& state, Value x = date.toNumber(state); } // Return ? FormatDateTimeToParts(dtf, x). - return IntlDateTimeFormat::formatToParts(state, thisValue.asObject(), x); + return dtf->formatToParts(state, x); } static void setFormatOpt(ExecutionState& state, Object* internalSlot, Object* result, const char* pName) @@ -262,28 +260,41 @@ static void setFormatOpt(ExecutionState& state, Object* internalSlot, Object* re static Value builtinIntlDateTimeFormatResolvedOptions(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) { - if (!thisValue.isObject() || !thisValue.asObject()->hasInternalSlot() || !thisValue.asObject()->internalSlot()->hasOwnProperty(state, ObjectPropertyName(state, state.context()->staticStrings().lazyInitializedDateTimeFormat()))) { + if (!thisValue.isObject() || !thisValue.asObject()->isIntlDateTimeFormatObject()) { ErrorObject::throwBuiltinError(state, ErrorObject::TypeError, "Method called on incompatible receiver"); } - Object* internalSlot = thisValue.asObject()->internalSlot(); - + IntlDateTimeFormatObject* intlDateTimeFormatObject = thisValue.asObject()->asIntlDateTimeFormatObject(); Object* result = new Object(state); - setFormatOpt(state, internalSlot, result, "locale"); - setFormatOpt(state, internalSlot, result, "calendar"); - setFormatOpt(state, internalSlot, result, "numberingSystem"); - setFormatOpt(state, internalSlot, result, "timeZone"); - setFormatOpt(state, internalSlot, result, "hourCycle"); - setFormatOpt(state, internalSlot, result, "hour12"); - setFormatOpt(state, internalSlot, result, "weekday"); - setFormatOpt(state, internalSlot, result, "era"); - setFormatOpt(state, internalSlot, result, "year"); - setFormatOpt(state, internalSlot, result, "month"); - setFormatOpt(state, internalSlot, result, "day"); - setFormatOpt(state, internalSlot, result, "hour"); - setFormatOpt(state, internalSlot, result, "minute"); - setFormatOpt(state, internalSlot, result, "second"); - setFormatOpt(state, internalSlot, result, "timeZoneName"); +#define SET_RESULT(name) \ + { \ + Value v(intlDateTimeFormatObject->name()); \ + if (!v.isUndefined()) { \ + const char s[] = #name; \ + result->defineOwnProperty(state, ObjectPropertyName(state, String::fromASCII(s, sizeof(s) - 1)), ObjectPropertyDescriptor(v, ObjectPropertyDescriptor::AllPresent)); \ + } \ + } + + SET_RESULT(locale); + SET_RESULT(calendar); + SET_RESULT(numberingSystem); + SET_RESULT(timeZone); + SET_RESULT(hourCycle); + SET_RESULT(hour12); + SET_RESULT(weekday); + SET_RESULT(era); + SET_RESULT(year); + SET_RESULT(month); + SET_RESULT(day); + SET_RESULT(dayPeriod); + SET_RESULT(hour); + SET_RESULT(minute); + SET_RESULT(second); + SET_RESULT(fractionalSecondDigits); + SET_RESULT(timeZoneName); + SET_RESULT(dateStyle); + SET_RESULT(timeStyle); +#undef SET_RESULT return Value(result); } @@ -928,14 +939,26 @@ static Value builtinIntlGetCanonicalLocales(ExecutionState& state, Value thisVal return Object::createArrayFromList(state, ll); } +void GlobalObject::initializeIntl(ExecutionState& state) +{ + ObjectPropertyNativeGetterSetterData* nativeData = new ObjectPropertyNativeGetterSetterData(true, false, true, + [](ExecutionState& state, Object* self, const Value& receiver, const EncodedValue& privateDataFromObjectPrivateArea) -> Value { + ASSERT(self->isGlobalObject()); + return self->asGlobalObject()->intl(); + }, + nullptr); + + defineNativeDataAccessorProperty(state, ObjectPropertyName(state.context()->staticStrings().Intl), nativeData, Value(Value::EmptyValue)); +} + void GlobalObject::installIntl(ExecutionState& state) { m_intl = new Object(state); m_intl->setGlobalIntrinsicObject(state); const StaticStrings* strings = &state.context()->staticStrings(); - defineOwnProperty(state, ObjectPropertyName(strings->Intl), - ObjectPropertyDescriptor(m_intl, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); + redefineOwnProperty(state, ObjectPropertyName(strings->Intl), + ObjectPropertyDescriptor(m_intl, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); m_intlCollator = new NativeFunctionObject(state, NativeFunctionInfo(strings->Collator, builtinIntlCollatorConstructor, 0), NativeFunctionObject::__ForBuiltinConstructor__); m_intlCollator->setGlobalIntrinsicObject(state); @@ -977,9 +1000,12 @@ void GlobalObject::installIntl(ExecutionState& state) m_intlNumberFormatPrototype = m_intlNumberFormat->getFunctionPrototype(state).asObject(); m_intlNumberFormatPrototype->setGlobalIntrinsicObject(state, true); - formatFunction = new NativeFunctionObject(state, NativeFunctionInfo(strings->getFormat, builtinIntlNumberFormatFormatGetter, 0, NativeFunctionInfo::Strict)); - m_intlNumberFormatPrototype->defineOwnProperty(state, state.context()->staticStrings().format, - ObjectPropertyDescriptor(JSGetterSetter(formatFunction, Value(Value::EmptyValue)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::ConfigurablePresent))); + { + formatFunction = new NativeFunctionObject(state, NativeFunctionInfo(strings->getFormat, builtinIntlNumberFormatFormatGetter, 0, NativeFunctionInfo::Strict)); + JSGetterSetter gs(formatFunction, Value()); + ObjectPropertyDescriptor desc(gs, ObjectPropertyDescriptor::ConfigurablePresent); + m_intlNumberFormatPrototype->defineOwnProperty(state, ObjectPropertyName(state, strings->format), desc); + } m_intlNumberFormatPrototype->defineOwnProperty(state, state.context()->staticStrings().formatToParts, ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->formatToParts, builtinIntlNumberFormatFormatToParts, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::ConfigurablePresent | ObjectPropertyDescriptor::WritablePresent))); @@ -1143,6 +1169,13 @@ void GlobalObject::installIntl(ExecutionState& state) m_intl->defineOwnProperty(state, ObjectPropertyName(strings->getCanonicalLocales), ObjectPropertyDescriptor(getCanonicalLocales, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); } -} // namespace Escargot + +#else + +void GlobalObject::initializeIntl(ExecutionState& state) +{ + // dummy initialize function +} #endif // ENABLE_ICU +} // namespace Escargot diff --git a/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinIterator.cpp b/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinIterator.cpp deleted file mode 100644 index 33edc15..0000000 --- a/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinIterator.cpp +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2018-present Samsung Electronics Co., Ltd - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - */ - -#include "Escargot.h" -#include "runtime/GlobalObject.h" -#include "runtime/Context.h" -#include "runtime/VMInstance.h" -#include "runtime/NativeFunctionObject.h" -#include "runtime/ToStringRecursionPreventer.h" - -namespace Escargot { - -static Value builtinIteratorIterator(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - return thisValue; -} - -void GlobalObject::installIterator(ExecutionState& state) -{ - m_iteratorPrototype = new Object(state); - m_iteratorPrototype->setGlobalIntrinsicObject(state, true); - - // https://www.ecma-international.org/ecma-262/10.0/index.html#sec-%iteratorprototype%-@@iterator - FunctionObject* fn = new NativeFunctionObject(state, NativeFunctionInfo(AtomicString(state, String::fromASCII("[Symbol.iterator]")), builtinIteratorIterator, 0, NativeFunctionInfo::Strict)); - m_iteratorPrototype->defineOwnPropertyThrowsException(state, ObjectPropertyName(state.context()->vmInstance()->globalSymbols().iterator), - ObjectPropertyDescriptor(fn, - (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); -} -} // namespace Escargot diff --git a/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinJSON.cpp b/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinJSON.cpp index 7f179ae..9036522 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinJSON.cpp +++ b/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinJSON.cpp @@ -711,6 +711,18 @@ static Value builtinJSONStringify(ExecutionState& state, Value thisValue, size_t return Value(); } +void GlobalObject::initializeJSON(ExecutionState& state) +{ + ObjectPropertyNativeGetterSetterData* nativeData = new ObjectPropertyNativeGetterSetterData(true, false, true, + [](ExecutionState& state, Object* self, const Value& receiver, const EncodedValue& privateDataFromObjectPrivateArea) -> Value { + ASSERT(self->isGlobalObject()); + return self->asGlobalObject()->json(); + }, + nullptr); + + defineNativeDataAccessorProperty(state, ObjectPropertyName(state.context()->staticStrings().JSON), nativeData, Value(Value::EmptyValue)); +} + void GlobalObject::installJSON(ExecutionState& state) { m_json = new Object(state); @@ -719,8 +731,8 @@ void GlobalObject::installJSON(ExecutionState& state) ObjectPropertyDescriptor(Value(state.context()->staticStrings().JSON.string()), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::ConfigurablePresent))); - defineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().JSON), - ObjectPropertyDescriptor(m_json, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); + redefineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().JSON), + ObjectPropertyDescriptor(m_json, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); m_jsonParse = new NativeFunctionObject(state, NativeFunctionInfo(state.context()->staticStrings().parse, builtinJSONParse, 2, NativeFunctionInfo::Strict)); m_json->defineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().parse), diff --git a/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinMap.cpp b/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinMap.cpp index d509e13..078fe2d 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinMap.cpp +++ b/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinMap.cpp @@ -194,8 +194,22 @@ static Value builtinMapIteratorNext(ExecutionState& state, Value thisValue, size return iter->next(state); } +void GlobalObject::initializeMap(ExecutionState& state) +{ + ObjectPropertyNativeGetterSetterData* nativeData = new ObjectPropertyNativeGetterSetterData(true, false, true, + [](ExecutionState& state, Object* self, const Value& receiver, const EncodedValue& privateDataFromObjectPrivateArea) -> Value { + ASSERT(self->isGlobalObject()); + return self->asGlobalObject()->map(); + }, + nullptr); + + defineNativeDataAccessorProperty(state, ObjectPropertyName(state.context()->staticStrings().Map), nativeData, Value(Value::EmptyValue)); +} + void GlobalObject::installMap(ExecutionState& state) { + ASSERT(!!m_iteratorPrototype); + m_map = new NativeFunctionObject(state, NativeFunctionInfo(state.context()->staticStrings().Map, builtinMapConstructor, 0), NativeFunctionObject::__ForBuiltinConstructor__); m_map->setGlobalIntrinsicObject(state); @@ -261,7 +275,7 @@ void GlobalObject::installMap(ExecutionState& state) m_map->setFunctionPrototype(state, m_mapPrototype); - defineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().Map), - ObjectPropertyDescriptor(m_map, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); + redefineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().Map), + ObjectPropertyDescriptor(m_map, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); } } // namespace Escargot diff --git a/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinMath.cpp b/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinMath.cpp index e54ae9f..543e2e3 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinMath.cpp +++ b/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinMath.cpp @@ -413,6 +413,18 @@ static Value builtinMathExpm1(ExecutionState& state, Value thisValue, size_t arg return Value(ieee754::expm1(x)); } +void GlobalObject::initializeMath(ExecutionState& state) +{ + ObjectPropertyNativeGetterSetterData* nativeData = new ObjectPropertyNativeGetterSetterData(true, false, true, + [](ExecutionState& state, Object* self, const Value& receiver, const EncodedValue& privateDataFromObjectPrivateArea) -> Value { + ASSERT(self->isGlobalObject()); + return self->asGlobalObject()->math(); + }, + nullptr); + + defineNativeDataAccessorProperty(state, ObjectPropertyName(state.context()->staticStrings().Math), nativeData, Value(Value::EmptyValue)); +} + void GlobalObject::installMath(ExecutionState& state) { m_math = new Object(state); @@ -546,7 +558,7 @@ void GlobalObject::installMath(ExecutionState& state) m_math->defineOwnPropertyThrowsException(state, ObjectPropertyName(state.context()->staticStrings().trunc), ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(state.context()->staticStrings().trunc, builtinMathTrunc, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - defineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().Math), - ObjectPropertyDescriptor(m_math, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); + redefineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().Math), + ObjectPropertyDescriptor(m_math, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); } } // namespace Escargot diff --git a/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinNumber.cpp b/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinNumber.cpp index e74e11a..e309398 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinNumber.cpp +++ b/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinNumber.cpp @@ -380,8 +380,22 @@ static Value builtinNumberIsSafeInteger(ExecutionState& state, Value thisValue, return Value(Value::False); } +void GlobalObject::initializeNumber(ExecutionState& state) +{ + ObjectPropertyNativeGetterSetterData* nativeData = new ObjectPropertyNativeGetterSetterData(true, false, true, + [](ExecutionState& state, Object* self, const Value& receiver, const EncodedValue& privateDataFromObjectPrivateArea) -> Value { + ASSERT(self->isGlobalObject()); + return self->asGlobalObject()->number(); + }, + nullptr); + + defineNativeDataAccessorProperty(state, ObjectPropertyName(state.context()->staticStrings().Number), nativeData, Value(Value::EmptyValue)); +} + void GlobalObject::installNumber(ExecutionState& state) { + ASSERT(!!m_parseInt && !!m_parseFloat); + const StaticStrings* strings = &state.context()->staticStrings(); m_number = new NativeFunctionObject(state, NativeFunctionInfo(strings->Number, builtinNumberConstructor, 1), NativeFunctionObject::__ForBuiltinConstructor__); m_number->setGlobalIntrinsicObject(state); @@ -430,6 +444,15 @@ void GlobalObject::installNumber(ExecutionState& state) // $20.1.2.3 Number.isNaN m_number->defineOwnPropertyThrowsException(state, strings->isNaN, ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->isNaN, builtinNumberIsNaN, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); + + m_number->defineOwnPropertyThrowsException(state, strings->parseInt, + ObjectPropertyDescriptor(m_parseInt, + (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); + + m_number->defineOwnProperty(state, ObjectPropertyName(strings->parseFloat), + ObjectPropertyDescriptor(m_parseFloat, + (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); + // $20.1.2.5 Number.isSafeInteger m_number->defineOwnPropertyThrowsException(state, strings->isSafeInteger, ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->isSafeInteger, builtinNumberIsSafeInteger, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); @@ -448,7 +471,9 @@ void GlobalObject::installNumber(ExecutionState& state) // $20.1.2.14 Number.POSITIVE_INFINITY m_number->defineOwnPropertyThrowsException(state, strings->POSITIVE_INFINITY, ObjectPropertyDescriptor(Value(std::numeric_limits::infinity()), allFalsePresent)); - defineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().Number), - ObjectPropertyDescriptor(m_number, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); + m_numberProxyObject = new NumberObject(state); + + redefineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().Number), + ObjectPropertyDescriptor(m_number, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); } } // namespace Escargot diff --git a/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinObject.cpp b/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinObject.cpp index f86b8a2..c2ce374 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinObject.cpp +++ b/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinObject.cpp @@ -156,6 +156,13 @@ static Value builtinObjectToString(ExecutionState& state, Value thisValue, size_ return strings->lazyObjectObjectToString().string(); } +static Value builtinObjectHasOwn(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) +{ + Object* obj = argv[0].toObject(state); + Value key = argv[1].toPropertyKey(state); + return Value(obj->hasOwnProperty(state, ObjectPropertyName(state, key))); +} + static Value builtinObjectHasOwnProperty(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) { Value key = argv[0].toPrimitive(state, Value::PrimitiveTypeHint::PreferString); @@ -629,6 +636,122 @@ static Value builtinObjectEntries(ExecutionState& state, Value thisValue, size_t return Object::createArrayFromList(state, nameList.size(), nameList.data()); } +// Object.prototype.__defineGetter__ ( P, getter ) +static Value builtinDefineGetter(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) +{ + // Let O be ? ToObject(this value). + Object* O = thisValue.toObject(state); + // If IsCallable(getter) is false, throw a TypeError exception. + if (!argv[1].isCallable()) { + ErrorObject::throwBuiltinError(state, ErrorObject::TypeError, String::emptyString, true, state.context()->staticStrings().__defineGetter__.string(), ErrorObject::Messages::GlobalObject_CallbackNotCallable); + } + // Let desc be PropertyDescriptor{[[Get]]: getter, [[Enumerable]]: true, [[Configurable]]: true}. + ObjectPropertyDescriptor desc(JSGetterSetter(argv[1].asObject(), Value(Value::EmptyValue)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::EnumerablePresent | ObjectPropertyDescriptor::ConfigurablePresent)); + + // Let key be ? ToPropertyKey(P). + ObjectPropertyName key(state, argv[0]); + +// Perform ? DefinePropertyOrThrow(O, key, desc). +#if defined(ENABLE_V8_LIKE_DEFINE_LOOKUP_GETTER_SETTER) + O->defineOwnProperty(state, key, desc); +#else + O->defineOwnPropertyThrowsException(state, key, desc); +#endif + + // Return undefined. + return Value(); +} + +// Object.prototype.__defineSetter__ ( P, getter ) +static Value builtinDefineSetter(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) +{ + // Let O be ? ToObject(this value). + Object* O = thisValue.toObject(state); + // If IsCallable(getter) is false, throw a TypeError exception. + if (!argv[1].isCallable()) { + ErrorObject::throwBuiltinError(state, ErrorObject::TypeError, String::emptyString, true, state.context()->staticStrings().__defineSetter__.string(), ErrorObject::Messages::GlobalObject_CallbackNotCallable); + } + // Let desc be PropertyDescriptor{[[Get]]: getter, [[Enumerable]]: true, [[Configurable]]: true}. + ObjectPropertyDescriptor desc(JSGetterSetter(Value(Value::EmptyValue), argv[1].asObject()), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::EnumerablePresent | ObjectPropertyDescriptor::ConfigurablePresent)); + + // Let key be ? ToPropertyKey(P). + ObjectPropertyName key(state, argv[0]); + +// Perform ? DefinePropertyOrThrow(O, key, desc). +#if defined(ENABLE_V8_LIKE_DEFINE_LOOKUP_GETTER_SETTER) + O->defineOwnProperty(state, key, desc); +#else + O->defineOwnPropertyThrowsException(state, key, desc); +#endif + + // Return undefined. + return Value(); +} + +// Object.prototype.__lookupGetter__ ( P, getter ) +static Value builtinLookupGetter(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) +{ + // Let O be ? ToObject(this value). + Object* O = thisValue.toObject(state); + // Let key be ? ToPropertyKey(P). + ObjectPropertyName key(state, argv[0]); + + // Repeat, + while (O) { + // Let desc be ? O.[[GetOwnProperty]](key). + auto desc = O->getOwnProperty(state, key); + + // If desc is not undefined, then + if (desc.hasValue()) { + // If IsAccessorDescriptor(desc) is true, return desc.[[Get]]. + if (!desc.isDataProperty() && desc.jsGetterSetter()->hasGetter()) { + return desc.jsGetterSetter()->getter(); + } + // Return undefined. + return Value(); + } + // Set O to ? O.[[GetPrototypeOf]](). + O = O->getPrototypeObject(state); + // If O is null, return undefined. + } + return Value(); +} + +// Object.prototype.__lookupSetter__ ( P, getter ) +static Value builtinLookupSetter(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) +{ + // Let O be ? ToObject(this value). + Object* O = thisValue.toObject(state); + // Let key be ? ToPropertyKey(P). + ObjectPropertyName key(state, argv[0]); + + // Repeat, + while (O) { + // Let desc be ? O.[[GetOwnProperty]](key). + auto desc = O->getOwnProperty(state, key); + + // If desc is not undefined, then + if (desc.hasValue()) { + // If IsAccessorDescriptor(desc) is true, return desc.[[Set]]. + if (!desc.isDataProperty() && desc.jsGetterSetter()->hasSetter()) { + return desc.jsGetterSetter()->setter(); + } + // Return undefined. + return Value(); + } + // Set O to ? O.[[GetPrototypeOf]](). + O = O->getPrototypeObject(state); + // If O is null, return undefined. + } + return Value(); +} + +void GlobalObject::initializeObject(ExecutionState& state) +{ + // Object should be installed at the start time + installObject(state); +} + void GlobalObject::installObject(ExecutionState& state) { const StaticStrings& strings = state.context()->staticStrings(); @@ -753,6 +876,10 @@ void GlobalObject::installObject(ExecutionState& state) ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings.entries, builtinObjectEntries, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); + // Object.hasOwn + m_object->defineOwnProperty(state, ObjectPropertyName(strings.hasOwn), + ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings.hasOwn, builtinObjectHasOwn, 2, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); + // $19.1.3.2 Object.prototype.hasOwnProperty(V) m_objectPrototype->defineOwnProperty(state, ObjectPropertyName(strings.hasOwnProperty), ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings.hasOwnProperty, builtinObjectHasOwnProperty, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); @@ -773,12 +900,38 @@ void GlobalObject::installObject(ExecutionState& state) m_objectPrototype->defineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().propertyIsEnumerable), ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(state.context()->staticStrings().propertyIsEnumerable, builtinObjectPropertyIsEnumerable, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); + auto defineLookupGetterSetterNativeFunctionFlag = +#if defined(ENABLE_V8_LIKE_DEFINE_LOOKUP_GETTER_SETTER) + 0; +#else + NativeFunctionInfo::Strict; +#endif + m_objectPrototype->defineOwnProperty(state, ObjectPropertyName(strings.__defineGetter__), + ObjectPropertyDescriptor(new NativeFunctionObject(state, + NativeFunctionInfo(strings.__defineGetter__, builtinDefineGetter, 2, defineLookupGetterSetterNativeFunctionFlag)), + (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); + + m_objectPrototype->defineOwnProperty(state, ObjectPropertyName(strings.__defineSetter__), + ObjectPropertyDescriptor(new NativeFunctionObject(state, + NativeFunctionInfo(strings.__defineSetter__, builtinDefineSetter, 2, defineLookupGetterSetterNativeFunctionFlag)), + (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); + + m_objectPrototype->defineOwnProperty(state, ObjectPropertyName(strings.__lookupGetter__), + ObjectPropertyDescriptor(new NativeFunctionObject(state, + NativeFunctionInfo(strings.__lookupGetter__, builtinLookupGetter, 1, defineLookupGetterSetterNativeFunctionFlag)), + (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); + + m_objectPrototype->defineOwnProperty(state, ObjectPropertyName(strings.__lookupSetter__), + ObjectPropertyDescriptor(new NativeFunctionObject(state, + NativeFunctionInfo(strings.__lookupSetter__, builtinLookupSetter, 1, defineLookupGetterSetterNativeFunctionFlag)), + (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); JSGetterSetter gs( new NativeFunctionObject(state, NativeFunctionInfo(strings.get__proto__, builtinObject__proto__Getter, 0, NativeFunctionInfo::Strict)), new NativeFunctionObject(state, NativeFunctionInfo(strings.set__proto__, builtinObject__proto__Setter, 1, NativeFunctionInfo::Strict))); ObjectPropertyDescriptor __proto__desc(gs, ObjectPropertyDescriptor::ConfigurablePresent); m_objectPrototype->defineOwnProperty(state, ObjectPropertyName(strings.__proto__), __proto__desc); + defineOwnProperty(state, ObjectPropertyName(strings.Object), ObjectPropertyDescriptor(m_object, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); diff --git a/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinPromise.cpp b/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinPromise.cpp index 4949c79..c9b68a3 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinPromise.cpp +++ b/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinPromise.cpp @@ -742,6 +742,18 @@ static Value builtinPromiseAny(ExecutionState& state, Value thisValue, size_t ar return result; } +void GlobalObject::initializePromise(ExecutionState& state) +{ + ObjectPropertyNativeGetterSetterData* nativeData = new ObjectPropertyNativeGetterSetterData(true, false, true, + [](ExecutionState& state, Object* self, const Value& receiver, const EncodedValue& privateDataFromObjectPrivateArea) -> Value { + ASSERT(self->isGlobalObject()); + return self->asGlobalObject()->promise(); + }, + nullptr); + + defineNativeDataAccessorProperty(state, ObjectPropertyName(state.context()->staticStrings().Promise), nativeData, Value(Value::EmptyValue)); +} + void GlobalObject::installPromise(ExecutionState& state) { const StaticStrings* strings = &state.context()->staticStrings(); @@ -806,7 +818,7 @@ void GlobalObject::installPromise(ExecutionState& state) (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - defineOwnProperty(state, ObjectPropertyName(strings->Promise), - ObjectPropertyDescriptor(m_promise, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); + redefineOwnProperty(state, ObjectPropertyName(strings->Promise), + ObjectPropertyDescriptor(m_promise, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); } } // namespace Escargot diff --git a/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinProxy.cpp b/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinProxy.cpp index c3f8ace..b2b2aef 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinProxy.cpp +++ b/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinProxy.cpp @@ -105,6 +105,18 @@ static Value builtinProxyRevocable(ExecutionState& state, Value thisValue, size_ return result; } +void GlobalObject::initializeProxy(ExecutionState& state) +{ + ObjectPropertyNativeGetterSetterData* nativeData = new ObjectPropertyNativeGetterSetterData(true, false, true, + [](ExecutionState& state, Object* self, const Value& receiver, const EncodedValue& privateDataFromObjectPrivateArea) -> Value { + ASSERT(self->isGlobalObject()); + return self->asGlobalObject()->proxy(); + }, + nullptr); + + defineNativeDataAccessorProperty(state, ObjectPropertyName(state.context()->staticStrings().Proxy), nativeData, Value(Value::EmptyValue)); +} + void GlobalObject::installProxy(ExecutionState& state) { const StaticStrings* strings = &state.context()->staticStrings(); @@ -113,7 +125,7 @@ void GlobalObject::installProxy(ExecutionState& state) m_proxy->defineOwnPropertyThrowsException(state, ObjectPropertyName(strings->revocable), ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->revocable, builtinProxyRevocable, 2, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - defineOwnProperty(state, ObjectPropertyName(strings->Proxy), - ObjectPropertyDescriptor(m_proxy, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); + redefineOwnProperty(state, ObjectPropertyName(strings->Proxy), + ObjectPropertyDescriptor(m_proxy, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); } } // namespace Escargot diff --git a/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinReflect.cpp b/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinReflect.cpp index ee8f6ef..4efa5cf 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinReflect.cpp +++ b/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinReflect.cpp @@ -280,6 +280,18 @@ static Value builtinReflectSetPrototypeOf(ExecutionState& state, Value thisValue return Value(target.asObject()->setPrototype(state, proto)); } +void GlobalObject::initializeReflect(ExecutionState& state) +{ + ObjectPropertyNativeGetterSetterData* nativeData = new ObjectPropertyNativeGetterSetterData(true, false, true, + [](ExecutionState& state, Object* self, const Value& receiver, const EncodedValue& privateDataFromObjectPrivateArea) -> Value { + ASSERT(self->isGlobalObject()); + return self->asGlobalObject()->reflect(); + }, + nullptr); + + defineNativeDataAccessorProperty(state, ObjectPropertyName(state.context()->staticStrings().Reflect), nativeData, Value(Value::EmptyValue)); +} + void GlobalObject::installReflect(ExecutionState& state) { const StaticStrings* strings = &state.context()->staticStrings(); @@ -328,7 +340,7 @@ void GlobalObject::installReflect(ExecutionState& state) m_reflect->defineOwnPropertyThrowsException(state, ObjectPropertyName(state, Value(state.context()->vmInstance()->globalSymbols().toStringTag)), ObjectPropertyDescriptor(state.context()->staticStrings().Reflect.string(), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::ConfigurablePresent))); - defineOwnProperty(state, ObjectPropertyName(strings->Reflect), - ObjectPropertyDescriptor(m_reflect, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); + redefineOwnProperty(state, ObjectPropertyName(strings->Reflect), + ObjectPropertyDescriptor(m_reflect, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); } } // namespace Escargot diff --git a/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinRegExp.cpp b/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinRegExp.cpp index ee14b7b..a502f88 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinRegExp.cpp +++ b/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinRegExp.cpp @@ -753,8 +753,22 @@ std::pair RegExpStringIteratorObject::advance(ExecutionState& state return std::make_pair(match, false); } +void GlobalObject::initializeRegExp(ExecutionState& state) +{ + ObjectPropertyNativeGetterSetterData* nativeData = new ObjectPropertyNativeGetterSetterData(true, false, true, + [](ExecutionState& state, Object* self, const Value& receiver, const EncodedValue& privateDataFromObjectPrivateArea) -> Value { + ASSERT(self->isGlobalObject()); + return self->asGlobalObject()->regexp(); + }, + nullptr); + + defineNativeDataAccessorProperty(state, ObjectPropertyName(state.context()->staticStrings().RegExp), nativeData, Value(Value::EmptyValue)); +} + void GlobalObject::installRegExp(ExecutionState& state) { + ASSERT(!!m_iteratorPrototype); + const StaticStrings* strings = &state.context()->staticStrings(); m_regexp = new NativeFunctionObject(state, NativeFunctionInfo(strings->RegExp, builtinRegExpConstructor, 2), NativeFunctionObject::__ForBuiltinConstructor__); @@ -921,7 +935,7 @@ void GlobalObject::installRegExp(ExecutionState& state) m_regexpStringIteratorPrototype->defineOwnPropertyThrowsException(state, ObjectPropertyName(state.context()->vmInstance()->globalSymbols().toStringTag), ObjectPropertyDescriptor(Value(String::fromASCII("RegExp String Iterator")), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::ConfigurablePresent))); - defineOwnProperty(state, ObjectPropertyName(strings->RegExp), - ObjectPropertyDescriptor(m_regexp, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); + redefineOwnProperty(state, ObjectPropertyName(strings->RegExp), + ObjectPropertyDescriptor(m_regexp, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); } } // namespace Escargot diff --git a/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinSet.cpp b/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinSet.cpp index 31c6823..0c37e18 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinSet.cpp +++ b/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinSet.cpp @@ -181,8 +181,22 @@ static Value builtinSetIteratorNext(ExecutionState& state, Value thisValue, size return iter->next(state); } +void GlobalObject::initializeSet(ExecutionState& state) +{ + ObjectPropertyNativeGetterSetterData* nativeData = new ObjectPropertyNativeGetterSetterData(true, false, true, + [](ExecutionState& state, Object* self, const Value& receiver, const EncodedValue& privateDataFromObjectPrivateArea) -> Value { + ASSERT(self->isGlobalObject()); + return self->asGlobalObject()->set(); + }, + nullptr); + + defineNativeDataAccessorProperty(state, ObjectPropertyName(state.context()->staticStrings().Set), nativeData, Value(Value::EmptyValue)); +} + void GlobalObject::installSet(ExecutionState& state) { + ASSERT(!!m_iteratorPrototype); + m_set = new NativeFunctionObject(state, NativeFunctionInfo(state.context()->staticStrings().Set, builtinSetConstructor, 0), NativeFunctionObject::__ForBuiltinConstructor__); m_set->setGlobalIntrinsicObject(state); @@ -241,7 +255,7 @@ void GlobalObject::installSet(ExecutionState& state) ObjectPropertyDescriptor(Value(String::fromASCII("Set Iterator")), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::ConfigurablePresent))); m_set->setFunctionPrototype(state, m_setPrototype); - defineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().Set), - ObjectPropertyDescriptor(m_set, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); + redefineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().Set), + ObjectPropertyDescriptor(m_set, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); } } // namespace Escargot diff --git a/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinSharedArrayBuffer.cpp b/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinSharedArrayBuffer.cpp index fc4ddb0..335ddd1 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinSharedArrayBuffer.cpp +++ b/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinSharedArrayBuffer.cpp @@ -17,8 +17,6 @@ * USA */ -#if defined(ENABLE_THREADING) - #include "Escargot.h" #include "runtime/GlobalObject.h" #include "runtime/Context.h" @@ -28,6 +26,8 @@ namespace Escargot { +#if defined(ENABLE_THREADING) + // https://262.ecma-international.org/#sec-sharedarraybuffer-constructor static Value builtinSharedArrayBufferConstructor(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) { @@ -84,6 +84,18 @@ static Value builtinSharedArrayBufferSlice(ExecutionState& state, Value thisValu return newBuffer; } +void GlobalObject::initializeSharedArrayBuffer(ExecutionState& state) +{ + ObjectPropertyNativeGetterSetterData* nativeData = new ObjectPropertyNativeGetterSetterData(true, false, true, + [](ExecutionState& state, Object* self, const Value& receiver, const EncodedValue& privateDataFromObjectPrivateArea) -> Value { + ASSERT(self->isGlobalObject()); + return self->asGlobalObject()->sharedArrayBuffer(); + }, + nullptr); + + defineNativeDataAccessorProperty(state, ObjectPropertyName(state.context()->staticStrings().SharedArrayBuffer), nativeData, Value(Value::EmptyValue)); +} + void GlobalObject::installSharedArrayBuffer(ExecutionState& state) { const StaticStrings* strings = &state.context()->staticStrings(); @@ -115,9 +127,16 @@ void GlobalObject::installSharedArrayBuffer(ExecutionState& state) m_sharedArrayBuffer->setFunctionPrototype(state, m_sharedArrayBufferPrototype); - defineOwnProperty(state, ObjectPropertyName(strings->SharedArrayBuffer), - ObjectPropertyDescriptor(m_sharedArrayBuffer, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); + redefineOwnProperty(state, ObjectPropertyName(strings->SharedArrayBuffer), + ObjectPropertyDescriptor(m_sharedArrayBuffer, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); +} + +#else + +void GlobalObject::initializeSharedArrayBuffer(ExecutionState& state) +{ + // dummy initialize function } -} // namespace Escargot #endif +} // namespace Escargot diff --git a/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinString.cpp b/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinString.cpp index 0f5ebb4..7770a9e 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinString.cpp +++ b/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinString.cpp @@ -1635,8 +1635,22 @@ static Value builtinStringIterator(ExecutionState& state, Value thisValue, size_ return new StringIteratorObject(state, S); } +void GlobalObject::initializeString(ExecutionState& state) +{ + ObjectPropertyNativeGetterSetterData* nativeData = new ObjectPropertyNativeGetterSetterData(true, false, true, + [](ExecutionState& state, Object* self, const Value& receiver, const EncodedValue& privateDataFromObjectPrivateArea) -> Value { + ASSERT(self->isGlobalObject()); + return self->asGlobalObject()->string(); + }, + nullptr); + + defineNativeDataAccessorProperty(state, ObjectPropertyName(state.context()->staticStrings().String), nativeData, Value(Value::EmptyValue)); +} + void GlobalObject::installString(ExecutionState& state) { + ASSERT(!!m_iteratorPrototype); + const StaticStrings* strings = &state.context()->staticStrings(); m_string = new NativeFunctionObject(state, NativeFunctionInfo(strings->String, builtinStringConstructor, 1), NativeFunctionObject::__ForBuiltinConstructor__); m_string->setGlobalIntrinsicObject(state); @@ -1827,7 +1841,9 @@ void GlobalObject::installString(ExecutionState& state) m_stringIteratorPrototype->defineOwnPropertyThrowsException(state, ObjectPropertyName(state.context()->vmInstance()->globalSymbols().toStringTag), ObjectPropertyDescriptor(Value(String::fromASCII("String Iterator")), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::ConfigurablePresent))); - defineOwnProperty(state, ObjectPropertyName(strings->String), - ObjectPropertyDescriptor(m_string, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); + m_stringProxyObject = new StringObject(state); + + redefineOwnProperty(state, ObjectPropertyName(strings->String), + ObjectPropertyDescriptor(m_string, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); } } // namespace Escargot diff --git a/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinSymbol.cpp b/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinSymbol.cpp index 5e848f6..d859031 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinSymbol.cpp +++ b/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinSymbol.cpp @@ -123,6 +123,18 @@ static Value builtinSymbolDescriptionGetter(ExecutionState& state, Value thisVal return Value(); } +void GlobalObject::initializeSymbol(ExecutionState& state) +{ + ObjectPropertyNativeGetterSetterData* nativeData = new ObjectPropertyNativeGetterSetterData(true, false, true, + [](ExecutionState& state, Object* self, const Value& receiver, const EncodedValue& privateDataFromObjectPrivateArea) -> Value { + ASSERT(self->isGlobalObject()); + return self->asGlobalObject()->symbol(); + }, + nullptr); + + defineNativeDataAccessorProperty(state, ObjectPropertyName(state.context()->staticStrings().Symbol), nativeData, Value(Value::EmptyValue)); +} + void GlobalObject::installSymbol(ExecutionState& state) { m_symbol = new NativeFunctionObject(state, NativeFunctionInfo(state.context()->staticStrings().Symbol, builtinSymbolConstructor, 0), NativeFunctionObject::__ForBuiltinConstructor__); @@ -168,7 +180,10 @@ void GlobalObject::installSymbol(ExecutionState& state) DEFINE_GLOBAL_SYMBOLS(DECLARE_GLOBAL_SYMBOLS); m_symbol->setFunctionPrototype(state, m_symbolPrototype); - defineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().Symbol), - ObjectPropertyDescriptor(m_symbol, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); + + m_symbolProxyObject = new SymbolObject(state, state.context()->vmInstance()->globalSymbols().iterator); + + redefineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().Symbol), + ObjectPropertyDescriptor(m_symbol, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); } } // namespace Escargot diff --git a/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinTypedArray.cpp b/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinTypedArray.cpp index 4b607e2..16861cb 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinTypedArray.cpp +++ b/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinTypedArray.cpp @@ -1069,6 +1069,8 @@ static Value builtinTypedArrayFilter(ExecutionState& state, Value thisValue, siz static Value builtinTypedArrayFind(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) { + Value predicate = argv[0]; + Value thisArg = argc > 1 ? argv[1] : Value(); // Let O be ToObject(this value). RESOLVE_THIS_BINDING_TO_OBJECT(O, TypedArray, find); // validateTypedArray is applied to the this value prior to evaluating the algorithm. @@ -1077,30 +1079,22 @@ static Value builtinTypedArrayFind(ExecutionState& state, Value thisValue, size_ // Array.prototype.find as defined in 22.1.3.8 except // that the this object’s [[ArrayLength]] internal slot is accessed // in place of performing a [[Get]] of "length" - double len = O->asTypedArrayObject()->arrayLength(); + size_t len = O->asTypedArrayObject()->arrayLength(); // If IsCallable(predicate) is false, throw a TypeError exception. - Value predicate = argv[0]; if (!predicate.isCallable()) { ErrorObject::throwBuiltinError(state, ErrorObject::TypeError, state.context()->staticStrings().TypedArray.string(), true, state.context()->staticStrings().find.string(), ErrorObject::Messages::GlobalObject_CallbackNotCallable); } - // If thisArg was supplied, let T be thisArg; else let T be undefined. - Value T; - if (argc > 1) { - T = argv[1]; - } - // Let k be 0. size_t k = 0; - Value kValue; // Repeat, while k < len while (k < len) { // Let kValue be Get(O, Pk). - kValue = O->getIndexedProperty(state, Value(k)).value(state, O); - // Let testResult be ToBoolean(Call(predicate, T, «kValue, k, O»)). + Value kValue = O->getIndexedProperty(state, Value(k)).value(state, O); + // Let testResult be ToBoolean(Call(predicate, thisArg, «kValue, k, O»)). Value args[] = { kValue, Value(k), O }; - bool testResult = Object::call(state, predicate, T, 3, args).toBoolean(state); + bool testResult = Object::call(state, predicate, thisArg, 3, args).toBoolean(state); // If testResult is true, return kValue. if (testResult) { return kValue; @@ -1114,6 +1108,8 @@ static Value builtinTypedArrayFind(ExecutionState& state, Value thisValue, size_ static Value builtinTypedArrayFindIndex(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) { + Value predicate = argv[0]; + Value thisArg = argc > 1 ? argv[1] : Value(); // Let O be ToObject(this value). RESOLVE_THIS_BINDING_TO_OBJECT(O, TypedArray, findIndex); // validateTypedArray is applied to the this value prior to evaluating the algorithm. @@ -1122,30 +1118,22 @@ static Value builtinTypedArrayFindIndex(ExecutionState& state, Value thisValue, // Array.prototype.findIndex as defined in 22.1.3.9 except // that the this object’s [[ArrayLength]] internal slot is accessed // in place of performing a [[Get]] of "length" - double len = O->asTypedArrayObject()->arrayLength(); + size_t len = O->asTypedArrayObject()->arrayLength(); // If IsCallable(predicate) is false, throw a TypeError exception. - Value predicate = argv[0]; if (!predicate.isCallable()) { ErrorObject::throwBuiltinError(state, ErrorObject::TypeError, state.context()->staticStrings().TypedArray.string(), true, state.context()->staticStrings().findIndex.string(), ErrorObject::Messages::GlobalObject_CallbackNotCallable); } - // If thisArg was supplied, let T be thisArg; else let T be undefined. - Value T; - if (argc > 1) { - T = argv[1]; - } - // Let k be 0. size_t k = 0; - Value kValue; // Repeat, while k < len while (k < len) { // Let kValue be ? Get(O, Pk). Value kValue = O->getIndexedProperty(state, Value(k)).value(state, O); - // Let testResult be ToBoolean(? Call(predicate, T, « kValue, k, O »)). + // Let testResult be ToBoolean(? Call(predicate, thisArg, « kValue, k, O »)). Value args[] = { kValue, Value(k), O }; - bool testResult = Object::call(state, predicate, T, 3, args).toBoolean(state); + bool testResult = Object::call(state, predicate, thisArg, 3, args).toBoolean(state); // If testResult is true, return k. if (testResult) { return Value(k); @@ -1157,6 +1145,82 @@ static Value builtinTypedArrayFindIndex(ExecutionState& state, Value thisValue, return Value(-1); } +static Value builtinTypedArrayFindLast(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) +{ + Value predicate = argv[0]; + Value thisArg = argc > 1 ? argv[1] : Value(); + // Let O be ToObject(this value). + RESOLVE_THIS_BINDING_TO_OBJECT(O, TypedArray, find); + // validateTypedArray is applied to the this value prior to evaluating the algorithm. + TypedArrayObject::validateTypedArray(state, O); + + // Let len be O.[[ArrayLength]]. + int64_t len = static_cast(O->asTypedArrayObject()->arrayLength()); + + // If IsCallable(predicate) is false, throw a TypeError exception. + if (!predicate.isCallable()) { + ErrorObject::throwBuiltinError(state, ErrorObject::TypeError, state.context()->staticStrings().TypedArray.string(), true, state.context()->staticStrings().findLast.string(), ErrorObject::Messages::GlobalObject_CallbackNotCallable); + } + + // Let k be len - 1. + int64_t k = len - 1; + Value kValue; + // Repeat, while k >= 0 + while (k >= 0) { + // Let kValue be Get(O, Pk). + kValue = O->getIndexedProperty(state, Value(k)).value(state, O); + // Let testResult be ToBoolean(Call(predicate, thisArg, «kValue, k, O»)). + Value args[] = { kValue, Value(k), O }; + bool testResult = Object::call(state, predicate, thisArg, 3, args).toBoolean(state); + // If testResult is true, return kValue. + if (testResult) { + return kValue; + } + // Set k to k - 1. + k--; + } + // Return undefined. + return Value(); +} + +static Value builtinTypedArrayFindLastIndex(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) +{ + Value predicate = argv[0]; + Value thisArg = argc > 1 ? argv[1] : Value(); + // Let O be ToObject(this value). + RESOLVE_THIS_BINDING_TO_OBJECT(O, TypedArray, findIndex); + // validateTypedArray is applied to the this value prior to evaluating the algorithm. + TypedArrayObject::validateTypedArray(state, O); + + // Let len be O.[[ArrayLength]]. + int64_t len = static_cast(O->asTypedArrayObject()->arrayLength()); + + // If IsCallable(predicate) is false, throw a TypeError exception. + if (!predicate.isCallable()) { + ErrorObject::throwBuiltinError(state, ErrorObject::TypeError, state.context()->staticStrings().TypedArray.string(), true, state.context()->staticStrings().findIndex.string(), ErrorObject::Messages::GlobalObject_CallbackNotCallable); + } + + // Let k be len - 1. + int64_t k = len - 1; + Value kValue; + // Repeat, while k >= 0 + while (k >= 0) { + // Let kValue be ? Get(O, Pk). + Value kValue = O->getIndexedProperty(state, Value(k)).value(state, O); + // Let testResult be ToBoolean(? Call(predicate, thisArg, « kValue, k, O »)). + Value args[] = { kValue, Value(k), O }; + bool testResult = Object::call(state, predicate, thisArg, 3, args).toBoolean(state); + // If testResult is true, return k. + if (testResult) { + return Value(k); + } + // Set k to k - 1. + k--; + } + // Return -1 + return Value(-1); +} + static Value builtinTypedArrayForEach(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) { // Let O be ToObject(this value). @@ -1605,14 +1669,35 @@ FunctionObject* GlobalObject::installTypedArray(ExecutionState& state, AtomicStr // 22.2.6.2 /TypedArray/.prototype.constructor taPrototype->defineOwnPropertyThrowsException(state, ObjectPropertyName(strings->constructor), ObjectPropertyDescriptor(taConstructor, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - defineOwnProperty(state, ObjectPropertyName(taName), - ObjectPropertyDescriptor(taConstructor, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); + redefineOwnProperty(state, ObjectPropertyName(taName), + ObjectPropertyDescriptor(taConstructor, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); return taConstructor; } +void GlobalObject::initializeTypedArray(ExecutionState& state) +{ + const StaticStrings* strings = &state.context()->staticStrings(); + +#define INITIALIZE_TYPEDARRAY(TYPE, type, siz, nativeType) \ + { \ + ObjectPropertyNativeGetterSetterData* nativeData = new ObjectPropertyNativeGetterSetterData(true, false, true, \ + [](ExecutionState& state, Object* self, const Value& receiver, const EncodedValue& privateDataFromObjectPrivateArea) -> Value { \ + ASSERT(self->isGlobalObject()); \ + return self->asGlobalObject()->type##Array(); \ + }, \ + nullptr); \ + defineNativeDataAccessorProperty(state, ObjectPropertyName(strings->TYPE##Array), nativeData, Value(Value::EmptyValue)); \ + } + + FOR_EACH_TYPEDARRAY_TYPES(INITIALIZE_TYPEDARRAY) +#undef INITIALIZE_TYPEDARRAY +} + void GlobalObject::installTypedArray(ExecutionState& state) { + ASSERT(!!m_arrayToString); + const StaticStrings* strings = &state.context()->staticStrings(); // %TypedArray% @@ -1654,6 +1739,10 @@ void GlobalObject::installTypedArray(ExecutionState& state) ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->find, builtinTypedArrayFind, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); typedArrayPrototype->defineOwnPropertyThrowsException(state, ObjectPropertyName(strings->findIndex), ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->findIndex, builtinTypedArrayFindIndex, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); + typedArrayPrototype->defineOwnPropertyThrowsException(state, ObjectPropertyName(strings->findLast), + ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->findLast, builtinTypedArrayFindLast, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); + typedArrayPrototype->defineOwnPropertyThrowsException(state, ObjectPropertyName(strings->findLastIndex), + ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->findLastIndex, builtinTypedArrayFindLastIndex, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); typedArrayPrototype->defineOwnPropertyThrowsException(state, ObjectPropertyName(strings->forEach), ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->forEach, builtinTypedArrayForEach, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); typedArrayPrototype->defineOwnPropertyThrowsException(state, ObjectPropertyName(strings->join), @@ -1673,10 +1762,9 @@ void GlobalObject::installTypedArray(ExecutionState& state) // https://www.ecma-international.org/ecma-262/10.0/#sec-%typedarray%.prototype.tostring // The initial value of the %TypedArray%.prototype.toString data property is the same built-in function object as the Array.prototype.toString method - ASSERT(!!m_arrayPrototype && m_arrayPrototype->hasOwnProperty(state, ObjectPropertyName(strings->toString))); - Value arrayToString = m_arrayPrototype->getOwnProperty(state, ObjectPropertyName(strings->toString)).value(state, m_arrayPrototype); typedArrayPrototype->defineOwnPropertyThrowsException(state, ObjectPropertyName(strings->toString), - ObjectPropertyDescriptor(arrayToString, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); + ObjectPropertyDescriptor(m_arrayToString, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); + typedArrayPrototype->defineOwnPropertyThrowsException(state, ObjectPropertyName(strings->indexOf), ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->indexOf, builtinTypedArrayIndexOf, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); typedArrayPrototype->defineOwnPropertyThrowsException(state, ObjectPropertyName(strings->lastIndexOf), diff --git a/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinWeakMap.cpp b/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinWeakMap.cpp index e272011..39c8825 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinWeakMap.cpp +++ b/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinWeakMap.cpp @@ -138,6 +138,18 @@ static Value builtinWeakMapSet(ExecutionState& state, Value thisValue, size_t ar return M; } +void GlobalObject::initializeWeakMap(ExecutionState& state) +{ + ObjectPropertyNativeGetterSetterData* nativeData = new ObjectPropertyNativeGetterSetterData(true, false, true, + [](ExecutionState& state, Object* self, const Value& receiver, const EncodedValue& privateDataFromObjectPrivateArea) -> Value { + ASSERT(self->isGlobalObject()); + return self->asGlobalObject()->weakMap(); + }, + nullptr); + + defineNativeDataAccessorProperty(state, ObjectPropertyName(state.context()->staticStrings().WeakMap), nativeData, Value(Value::EmptyValue)); +} + void GlobalObject::installWeakMap(ExecutionState& state) { m_weakMap = new NativeFunctionObject(state, NativeFunctionInfo(state.context()->staticStrings().WeakMap, builtinWeakMapConstructor, 0), NativeFunctionObject::__ForBuiltinConstructor__); @@ -163,7 +175,7 @@ void GlobalObject::installWeakMap(ExecutionState& state) ObjectPropertyDescriptor(Value(state.context()->staticStrings().WeakMap.string()), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::ConfigurablePresent))); m_weakMap->setFunctionPrototype(state, m_weakMapPrototype); - defineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().WeakMap), - ObjectPropertyDescriptor(m_weakMap, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); + redefineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().WeakMap), + ObjectPropertyDescriptor(m_weakMap, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); } } // namespace Escargot diff --git a/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinWeakRef.cpp b/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinWeakRef.cpp index b5c122e..b0dbcaf 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinWeakRef.cpp +++ b/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinWeakRef.cpp @@ -55,6 +55,17 @@ static Value builtinWeakRefDeRef(ExecutionState& state, Value thisValue, size_t return weakRef->targetAsValue(); } +void GlobalObject::initializeWeakRef(ExecutionState& state) +{ + ObjectPropertyNativeGetterSetterData* nativeData = new ObjectPropertyNativeGetterSetterData(true, false, true, + [](ExecutionState& state, Object* self, const Value& receiver, const EncodedValue& privateDataFromObjectPrivateArea) -> Value { + ASSERT(self->isGlobalObject()); + return self->asGlobalObject()->weakRef(); + }, + nullptr); + + defineNativeDataAccessorProperty(state, ObjectPropertyName(state.context()->staticStrings().WeakRef), nativeData, Value(Value::EmptyValue)); +} void GlobalObject::installWeakRef(ExecutionState& state) { @@ -73,7 +84,7 @@ void GlobalObject::installWeakRef(ExecutionState& state) ObjectPropertyDescriptor(Value(state.context()->staticStrings().WeakRef.string()), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::ConfigurablePresent))); m_weakRef->setFunctionPrototype(state, m_weakRefPrototype); - defineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().WeakRef), - ObjectPropertyDescriptor(m_weakRef, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); + redefineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().WeakRef), + ObjectPropertyDescriptor(m_weakRef, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); } } // namespace Escargot diff --git a/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinWeakSet.cpp b/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinWeakSet.cpp index a73d967..5a72891 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinWeakSet.cpp +++ b/lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinWeakSet.cpp @@ -126,6 +126,18 @@ static Value builtinWeakSetHas(ExecutionState& state, Value thisValue, size_t ar return Value(S->has(state, argv[0].asObject())); } +void GlobalObject::initializeWeakSet(ExecutionState& state) +{ + ObjectPropertyNativeGetterSetterData* nativeData = new ObjectPropertyNativeGetterSetterData(true, false, true, + [](ExecutionState& state, Object* self, const Value& receiver, const EncodedValue& privateDataFromObjectPrivateArea) -> Value { + ASSERT(self->isGlobalObject()); + return self->asGlobalObject()->weakSet(); + }, + nullptr); + + defineNativeDataAccessorProperty(state, ObjectPropertyName(state.context()->staticStrings().WeakSet), nativeData, Value(Value::EmptyValue)); +} + void GlobalObject::installWeakSet(ExecutionState& state) { m_weakSet = new NativeFunctionObject(state, NativeFunctionInfo(state.context()->staticStrings().WeakSet, builtinWeakSetConstructor, 0), NativeFunctionObject::__ForBuiltinConstructor__); @@ -149,7 +161,7 @@ void GlobalObject::installWeakSet(ExecutionState& state) ObjectPropertyDescriptor(Value(state.context()->staticStrings().WeakSet.string()), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::ConfigurablePresent))); m_weakSet->setFunctionPrototype(state, m_weakSetPrototype); - defineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().WeakSet), - ObjectPropertyDescriptor(m_weakSet, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); + redefineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().WeakSet), + ObjectPropertyDescriptor(m_weakSet, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); } } // namespace Escargot diff --git a/lwnode/code/escargotshim/deps/escargot/src/interpreter/ByteCode.cpp b/lwnode/code/escargotshim/deps/escargot/src/interpreter/ByteCode.cpp index 57c3ab8..18a1947 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/interpreter/ByteCode.cpp +++ b/lwnode/code/escargotshim/deps/escargot/src/interpreter/ByteCode.cpp @@ -30,6 +30,10 @@ namespace Escargot { OpcodeTable g_opcodeTable; +#ifndef NDEBUG +// Represent start code position which is used for bytecode dump +static MAY_THREAD_LOCAL size_t g_dumpCodeStartPosition; +#endif OpcodeTable::OpcodeTable() { @@ -40,40 +44,63 @@ OpcodeTable::OpcodeTable() } #ifndef NDEBUG -void ByteCode::dumpCode(size_t pos, const char* byteCodeStart) +void ByteCode::dumpCode(const char* byteCodeStart, const size_t endPos) { - printf("%d\t\t", (int)pos); + // set the start code position + g_dumpCodeStartPosition = (size_t)byteCodeStart; + + size_t curPos = 0; + while (curPos < endPos) { + ByteCode* curCode = (ByteCode*)(byteCodeStart + curPos); - const char* opcodeName = NULL; - switch (m_orgOpcode) { + printf("%zu\t\t", curPos); + + const char* opcodeName = nullptr; + switch (curCode->m_orgOpcode) { #define RETURN_BYTECODE_NAME(name, pushCount, popCount) \ case name##Opcode: \ - ((name*)this)->dump(byteCodeStart); \ + static_cast(curCode)->dump(); \ opcodeName = #name; \ break; - FOR_EACH_BYTECODE_OP(RETURN_BYTECODE_NAME) + FOR_EACH_BYTECODE_OP(RETURN_BYTECODE_NAME) #undef RETURN_BYTECODE_NAME - default: - RELEASE_ASSERT_NOT_REACHED(); - } + default: + RELEASE_ASSERT_NOT_REACHED(); + } - printf(" | %s ", opcodeName); - printf("(line: %d:%d)\n", (int)m_loc.line, (int)m_loc.column); + printf(" | %s ", opcodeName); + printf("(line: %zu:%zu)\n", curCode->m_loc.line, curCode->m_loc.column); + + if (curCode->m_orgOpcode == ExecutionPauseOpcode) { + if (static_cast(curCode)->m_reason == ExecutionPause::Yield) { + curPos += static_cast(curCode)->m_yieldData.m_tailDataLength; + } else if (static_cast(curCode)->m_reason == ExecutionPause::Await) { + curPos += static_cast(curCode)->m_awaitData.m_tailDataLength; + } else if (static_cast(curCode)->m_reason == ExecutionPause::GeneratorsInitialize) { + curPos += static_cast(curCode)->m_asyncGeneratorInitializeData.m_tailDataLength; + } else { + ASSERT_NOT_REACHED(); + } + } + + curPos += byteCodeLengths[curCode->m_orgOpcode]; + } } -int ByteCode::dumpJumpPosition(size_t pos, const char* byteCodeStart) +size_t ByteCode::dumpJumpPosition(size_t pos) { - return (int)(pos - (size_t)byteCodeStart); + ASSERT(!!g_dumpCodeStartPosition && pos > g_dumpCodeStartPosition); + return (pos - g_dumpCodeStartPosition); } -void GetGlobalVariable::dump(const char* byteCodeStart) +void GetGlobalVariable::dump() { - printf("get global variable r%d <- global.%s", (int)m_registerIndex, m_slot->m_propertyName.string()->toUTF8StringData().data()); + printf("get global variable r%u <- global.%s", m_registerIndex, m_slot->m_propertyName.string()->toUTF8StringData().data()); } -void SetGlobalVariable::dump(const char* byteCodeStart) +void SetGlobalVariable::dump() { - printf("set global variable global.%s <- r%d", m_slot->m_propertyName.string()->toUTF8StringData().data(), (int)m_registerIndex); + printf("set global variable global.%s <- r%u", m_slot->m_propertyName.string()->toUTF8StringData().data(), m_registerIndex); } #endif diff --git a/lwnode/code/escargotshim/deps/escargot/src/interpreter/ByteCode.h b/lwnode/code/escargotshim/deps/escargot/src/interpreter/ByteCode.h index 643158a..1f6cdda 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/interpreter/ByteCode.h +++ b/lwnode/code/escargotshim/deps/escargot/src/interpreter/ByteCode.h @@ -222,8 +222,8 @@ public: ByteCodeLOC m_loc; Opcode m_orgOpcode; - void dumpCode(size_t pos, const char* byteCodeStart); - int dumpJumpPosition(size_t pos, const char* byteCodeStart); + static void dumpCode(const char* byteCodeStart, const size_t endPos); + static size_t dumpJumpPosition(size_t pos); #endif }; @@ -239,9 +239,9 @@ public: Value m_value; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { - printf("load r%d <- ", (int)m_registerIndex); + printf("load r%u <- ", m_registerIndex); Value v = m_value; if (v.isNumber()) { printf("%lf", v.asNumber()); @@ -278,9 +278,9 @@ public: ByteCodeRegisterIndex m_registerIndex; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { - printf("r%d <- new.target", (int)m_registerIndex); + printf("r%u <- new.target", m_registerIndex); } #endif }; @@ -299,9 +299,9 @@ public: AtomicString m_name; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { - printf("load r%d <- %s", (int)m_registerIndex, m_name.string()->toUTF8StringData().data()); + printf("load r%u <- %s", m_registerIndex, m_name.string()->toUTF8StringData().data()); } #endif }; @@ -318,9 +318,9 @@ public: AtomicString m_name; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { - printf("store %s <- r%d", m_name.string()->toUTF8StringData().data(), (int)m_registerIndex); + printf("store %s <- r%u", m_name.string()->toUTF8StringData().data(), m_registerIndex); } #endif }; @@ -340,9 +340,9 @@ public: AtomicString m_name; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { - printf("initialize %s <- r%d", m_name.string()->toUTF8StringData().data(), (int)m_registerIndex); + printf("initialize %s <- r%u", m_name.string()->toUTF8StringData().data(), m_registerIndex); } #endif }; @@ -363,9 +363,9 @@ public: ByteCodeRegisterIndex m_index; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { - printf("load r%d <- heap[%d][%d]", (int)m_registerIndex, (int)m_upperIndex, (int)m_index); + printf("load r%u <- heap[%u][%u]", m_registerIndex, m_upperIndex, m_index); } #endif }; @@ -384,9 +384,9 @@ public: ByteCodeRegisterIndex m_index; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { - printf("store heap[%d][%d] <- r%d", (int)m_upperIndex, (int)m_index, (int)m_registerIndex); + printf("store heap[%u][%u] <- r%u", m_upperIndex, m_index, m_registerIndex); } #endif }; @@ -403,9 +403,9 @@ public: ByteCodeRegisterIndex m_index; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { - printf("initialize heap[0][%d] <- r%d", (int)m_index, (int)m_registerIndex); + printf("initialize heap[0][%u] <- r%u", m_index, m_registerIndex); } #endif }; @@ -424,13 +424,13 @@ public: ByteCodeRegisterIndex m_homeObjectRegisterIndex; InterpretedCodeBlock* m_codeBlock; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { printf("create "); if (m_codeBlock->isArrowFunctionExpression()) { printf("arrow"); } - printf("function %s -> r%d", m_codeBlock->functionName().string()->toUTF8StringData().data(), (int)m_registerIndex); + printf("function %s -> r%u", m_codeBlock->functionName().string()->toUTF8StringData().data(), m_registerIndex); } #endif }; @@ -630,35 +630,35 @@ public: }; // SetStaticPrivateFieldData }; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { if (m_stage == Stage::CreateClass) { if (m_superClassRegisterIndex == REGISTER_LIMIT) { - printf("create class r%d { r%d }", (int)m_classConstructorRegisterIndex, (int)m_classPrototypeRegisterIndex); + printf("create class r%u { r%u }", m_classConstructorRegisterIndex, m_classPrototypeRegisterIndex); } else { - printf("create class r%d : r%d { r%d }", (int)m_classConstructorRegisterIndex, (int)m_superClassRegisterIndex, (int)m_classPrototypeRegisterIndex); + printf("create class r%u : r%u { r%u }", m_classConstructorRegisterIndex, m_superClassRegisterIndex, m_classPrototypeRegisterIndex); } } else if (m_stage == Stage::SetFieldSize) { - printf("set field size r%d -> %d,%d", (int)m_classConstructorRegisterIndex, (int)m_fieldSize, (int)m_staticFieldSize); + printf("set field size r%u -> %u,%u", m_classConstructorRegisterIndex, m_fieldSize, m_staticFieldSize); } else if (m_stage == Stage::InitField) { - printf("init field r%d[%d, r%d]", (int)m_classConstructorRegisterIndex, (int)m_initFieldIndex, (int)m_propertyInitRegisterIndex); + printf("init field r%u[%u, r%u]", m_classConstructorRegisterIndex, m_initFieldIndex, m_propertyInitRegisterIndex); } else if (m_stage == Stage::InitPrivateField) { - printf("init private field r%d[%d, r%d] type %d", (int)m_classConstructorRegisterIndex, (int)m_initPrivateFieldIndex, (int)m_privatePropertyInitRegisterIndex, (int)m_initPrivateFieldType); + printf("init private field r%u[%u, r%u] type %u", m_classConstructorRegisterIndex, m_initPrivateFieldIndex, m_privatePropertyInitRegisterIndex, m_initPrivateFieldType); } else if (m_stage == Stage::SetFieldData) { - printf("set field data r%d[%d] = r%d", (int)m_classConstructorRegisterIndex, (int)m_setFieldIndex, (int)m_propertySetRegisterIndex); + printf("set field data r%u[%u] = r%u", m_classConstructorRegisterIndex, m_setFieldIndex, m_propertySetRegisterIndex); } else if (m_stage == Stage::SetPrivateFieldData) { - printf("set private field data r%d[%d] = r%d type %d", (int)m_classConstructorRegisterIndex, (int)m_setPrivateFieldIndex, (int)m_privatePropertySetRegisterIndex, (int)m_setPrivateFieldType); + printf("set private field data r%u[%u] = r%u type %u", m_classConstructorRegisterIndex, m_setPrivateFieldIndex, m_privatePropertySetRegisterIndex, m_setPrivateFieldType); } else if (m_stage == Stage::InitStaticField) { - printf("init static field r%d.r%d", (int)m_classConstructorRegisterIndex, (int)m_staticPropertyInitRegisterIndex); + printf("init static field r%u.r%u", m_classConstructorRegisterIndex, m_staticPropertyInitRegisterIndex); } else if (m_stage == Stage::InitStaticPrivateField) { - printf("init private static field r%d.r%d", (int)m_classConstructorRegisterIndex, (int)m_staticPrivatePropertyInitRegisterIndex); + printf("init private static field r%u.r%u", m_classConstructorRegisterIndex, m_staticPrivatePropertyInitRegisterIndex); } else if (m_stage == Stage::SetStaticFieldData) { - printf("set static field r%d.? = r%d", (int)m_classConstructorRegisterIndex, (int)m_staticPropertySetRegisterIndex); + printf("set static field r%u.? = r%u", m_classConstructorRegisterIndex, m_staticPropertySetRegisterIndex); } else if (m_stage == Stage::SetStaticPrivateFieldData) { - printf("set static private field r%d.? = r%d(%d)", (int)m_classConstructorRegisterIndex, (int)m_staticPrivatePropertySetRegisterIndex, (int)m_setStaticPrivateFieldType); + printf("set static private field r%u.? = r%u(%u)", m_classConstructorRegisterIndex, m_staticPrivatePropertySetRegisterIndex, m_setStaticPrivateFieldType); } else { ASSERT(m_stage == Stage::CleanupStaticData); - printf("cleanup static field data r%d", (int)m_classConstructorRegisterIndex); + printf("cleanup static field data r%u", m_classConstructorRegisterIndex); } } #endif @@ -674,9 +674,9 @@ public: ByteCodeRegisterIndex m_registerIndex; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { - printf("Create RestElement -> r%d", (int)m_registerIndex); + printf("Create RestElement -> r%u", m_registerIndex); } #endif }; @@ -693,12 +693,12 @@ public: ByteCodeRegisterIndex m_dstIndex : REGISTER_INDEX_IN_BIT; bool m_isCall : 1; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { if (m_isCall) { - printf("super constructor -> r%d", (int)m_dstIndex); + printf("super constructor -> r%u", m_dstIndex); } else { - printf("super property -> r%d", (int)m_dstIndex); + printf("super property -> r%u", m_dstIndex); } } #endif @@ -741,14 +741,14 @@ public: }; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { if (m_type == Super) { - printf("set object complex(r%d).r%d <- r%d", (int)m_objectRegisterIndex, (int)m_propertyNameIndex, (int)m_loadRegisterIndex); + printf("set object complex(r%u).r%u <- r%u", m_objectRegisterIndex, m_propertyNameIndex, m_loadRegisterIndex); } else { ASSERT(m_type == Private || m_type == PrivateWithoutOuterClass); - printf("set object complex(r%d).#%s <- r%d %s", (int)m_objectRegisterIndex, - m_propertyName.string()->toNonGCUTF8StringData().data(), (int)m_loadRegisterIndex, + printf("set object complex(r%u).#%s <- r%u %s", m_objectRegisterIndex, + m_propertyName.string()->toNonGCUTF8StringData().data(), m_loadRegisterIndex, m_type == Private ? "refer outer class" : ""); } } @@ -790,13 +790,13 @@ public: }; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { if (m_type == Super) { - printf("get object r%d <- complex(r%d).r%d", (int)m_storeRegisterIndex, (int)m_objectRegisterIndex, (int)m_propertyNameIndex); + printf("get object r%u <- complex(r%u).r%u", m_storeRegisterIndex, m_objectRegisterIndex, m_propertyNameIndex); } else { ASSERT(m_type == Private || m_type == PrivateWithoutOuterClass); - printf("get object r%d <- complex(r%d).#%s %s", (int)m_storeRegisterIndex, (int)m_objectRegisterIndex, + printf("get object r%u <- complex(r%u).#%s %s", m_storeRegisterIndex, m_objectRegisterIndex, m_propertyName.string()->toNonGCUTF8StringData().data(), m_type == Private ? "refer outer class" : ""); } } @@ -813,9 +813,9 @@ public: ByteCodeRegisterIndex m_dstIndex; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { - printf("load this binding -> r%d", (int)m_dstIndex); + printf("load this binding -> r%u", m_dstIndex); } #endif }; @@ -823,10 +823,10 @@ public: #ifdef NDEBUG #define DEFINE_BINARY_OPERATION_DUMP(name) #else -#define DEFINE_BINARY_OPERATION_DUMP(name) \ - void dump(const char* byteCodeStart) \ - { \ - printf(name " r%d <- r%d , r%d", (int)m_dstIndex, (int)m_srcIndex0, (int)m_srcIndex1); \ +#define DEFINE_BINARY_OPERATION_DUMP(name) \ + void dump() \ + { \ + printf(name " r%u <- r%u , r%u", m_dstIndex, m_srcIndex0, m_srcIndex1); \ } #endif @@ -877,7 +877,7 @@ public: } #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { printf("breakpointDisabled"); } @@ -892,7 +892,7 @@ public: } #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { printf("breakpointEnabled"); } @@ -910,9 +910,9 @@ public: ByteCodeRegisterIndex m_registerIndex; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { - printf("createobject -> r%d", (int)m_registerIndex); + printf("createobject -> r%u", m_registerIndex); } #endif }; @@ -930,9 +930,9 @@ public: size_t m_length; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { - printf("createarray -> r%d", (int)m_registerIndex); + printf("createarray -> r%u", m_registerIndex); } #endif }; @@ -950,9 +950,9 @@ public: ByteCodeRegisterIndex m_argumentIndex; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { - printf("create spread array object(r%d) -> r%d", (int)m_argumentIndex, (int)m_registerIndex); + printf("create spread array object(r%u) -> r%u", m_argumentIndex, m_registerIndex); } #endif }; @@ -972,9 +972,9 @@ public: ByteCodeRegisterIndex m_storeRegisterIndex; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { - printf("get object r%d <- r%d[r%d]", (int)m_storeRegisterIndex, (int)m_objectRegisterIndex, (int)m_propertyRegisterIndex); + printf("get object r%u <- r%u[r%u]", m_storeRegisterIndex, m_objectRegisterIndex, m_propertyRegisterIndex); } #endif }; @@ -994,9 +994,9 @@ public: ByteCodeRegisterIndex m_loadRegisterIndex; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { - printf("set object r%d[r%d] <- r%d", (int)m_objectRegisterIndex, (int)m_propertyRegisterIndex, (int)m_loadRegisterIndex); + printf("set object r%u[r%u] <- r%u", m_objectRegisterIndex, m_propertyRegisterIndex, m_loadRegisterIndex); } #endif }; @@ -1020,9 +1020,9 @@ public: bool m_redefineFunctionOrClassName : 1; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { - printf("object define own property r%d[r%d] <- r%d", (int)m_objectRegisterIndex, (int)m_propertyRegisterIndex, (int)m_loadRegisterIndex); + printf("object define own property r%u[r%u] <- r%u", m_objectRegisterIndex, m_propertyRegisterIndex, m_loadRegisterIndex); } #endif }; @@ -1046,9 +1046,9 @@ public: ObjectPropertyDescriptor::PresentAttribute m_presentAttribute : 8; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { - printf("object define own property with name r%d.%s <- r%d", (int)m_objectRegisterIndex, m_propertyName.string()->toUTF8StringData().data(), (int)m_loadRegisterIndex); + printf("object define own property with name r%u.%s <- r%u", m_objectRegisterIndex, m_propertyName.string()->toUTF8StringData().data(), m_loadRegisterIndex); } #endif }; @@ -1073,14 +1073,14 @@ public: ByteCodeRegisterIndex m_loadRegisterIndexs[ARRAY_DEFINE_OPERATION_MERGE_COUNT]; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { - printf("array define own property r%d[%d - %d] <- ", (int)m_objectRegisterIndex, (int)m_baseIndex, (int)(m_baseIndex + m_count)); + printf("array define own property r%u[%u - %u] <- ", m_objectRegisterIndex, m_baseIndex, (m_baseIndex + m_count)); for (int i = 0; i < m_count; i++) { if (m_loadRegisterIndexs[i] == REGISTER_LIMIT) { printf(", "); } else { - printf("r%d, ", m_loadRegisterIndexs[i]); + printf("r%u, ", m_loadRegisterIndexs[i]); } } } @@ -1101,14 +1101,14 @@ public: ByteCodeRegisterIndex m_loadRegisterIndexs[ARRAY_DEFINE_OPERATION_MERGE_COUNT]; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { - printf("array define own property by spread element r%d[ - ] <- ", (int)m_objectRegisterIndex); + printf("array define own property by spread element r%u[ - ] <- ", m_objectRegisterIndex); for (int i = 0; i < m_count; i++) { if (m_loadRegisterIndexs[i] == REGISTER_LIMIT) { printf(", "); } else { - printf("r%d, ", m_loadRegisterIndexs[i]); + printf("r%u, ", m_loadRegisterIndexs[i]); } } } @@ -1166,9 +1166,9 @@ public: ByteCodeRegisterIndex m_storeRegisterIndex; ObjectStructurePropertyName m_propertyName; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { - printf("get object r%d <- r%d.%s", (int)m_storeRegisterIndex, (int)m_objectRegisterIndex, m_propertyName.plainString()->toUTF8StringData().data()); + printf("get object r%u <- r%u.%s", m_storeRegisterIndex, m_objectRegisterIndex, m_propertyName.plainString()->toUTF8StringData().data()); } #endif }; @@ -1220,9 +1220,9 @@ public: bool m_isLength : 1; uint16_t m_missCount : 16; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { - printf("set object r%d.%s <- r%d", (int)m_objectRegisterIndex, m_propertyName.plainString()->toUTF8StringData().data(), (int)m_loadRegisterIndex); + printf("set object r%u.%s <- r%u", m_objectRegisterIndex, m_propertyName.plainString()->toUTF8StringData().data(), m_loadRegisterIndex); } #endif }; @@ -1240,7 +1240,7 @@ public: GlobalVariableAccessCacheItem* m_slot; #ifndef NDEBUG - void dump(const char* byteCodeStart); + void dump(); #endif }; @@ -1257,7 +1257,7 @@ public: GlobalVariableAccessCacheItem* m_slot; #ifndef NDEBUG - void dump(const char* byteCodeStart); + void dump(); #endif }; @@ -1274,9 +1274,9 @@ public: AtomicString m_variableName; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { - printf("initialize global variable %s <- r%d", m_variableName.string()->toUTF8StringData().data(), (int)m_registerIndex); + printf("initialize global variable %s <- r%u", m_variableName.string()->toUTF8StringData().data(), m_registerIndex); } #endif }; @@ -1294,9 +1294,9 @@ public: ByteCodeRegisterIndex m_registerIndex1; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { - printf("mov r%d <- r%d", (int)m_registerIndex1, (int)m_registerIndex0); + printf("mov r%u <- r%u", m_registerIndex1, m_registerIndex0); } #endif }; @@ -1314,9 +1314,9 @@ public: ByteCodeRegisterIndex m_dstIndex; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { - printf("to number r%d <- r%d", (int)m_dstIndex, (int)m_srcIndex); + printf("to number r%u <- r%u", m_dstIndex, m_srcIndex); } #endif }; @@ -1334,9 +1334,9 @@ public: ByteCodeRegisterIndex m_dstIndex; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { - printf("increment r%d <- r%d", (int)m_dstIndex, (int)m_srcIndex); + printf("increment r%u <- r%u", m_dstIndex, m_srcIndex); } #endif }; @@ -1356,9 +1356,9 @@ public: ByteCodeRegisterIndex m_dstIndex; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { - printf("to numeric increment(r%d) -> r%d, r%d", (int)m_srcIndex, (int)m_storeIndex, (int)m_dstIndex); + printf("to numeric increment(r%u) -> r%u, r%u", m_srcIndex, m_storeIndex, m_dstIndex); } #endif }; @@ -1376,9 +1376,9 @@ public: ByteCodeRegisterIndex m_dstIndex; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { - printf("decrement r%d <- r%d", (int)m_dstIndex, (int)m_srcIndex); + printf("decrement r%u <- r%u", m_dstIndex, m_srcIndex); } #endif }; @@ -1398,9 +1398,9 @@ public: ByteCodeRegisterIndex m_dstIndex; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { - printf("to numeric decrement(r%d) -> r%d, r%d", (int)m_srcIndex, (int)m_storeIndex, (int)m_dstIndex); + printf("to numeric decrement(r%u) -> r%u, r%u", m_srcIndex, m_storeIndex, m_dstIndex); } #endif }; @@ -1418,9 +1418,9 @@ public: ByteCodeRegisterIndex m_dstIndex; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { - printf("unary minus r%d <- r%d", (int)m_dstIndex, (int)m_srcIndex); + printf("unary minus r%u <- r%u", m_dstIndex, m_srcIndex); } #endif }; @@ -1438,9 +1438,9 @@ public: ByteCodeRegisterIndex m_dstIndex; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { - printf("unary not r%d <- r%d", (int)m_dstIndex, (int)m_srcIndex); + printf("unary not r%u <- r%u", m_dstIndex, m_srcIndex); } #endif }; @@ -1458,9 +1458,9 @@ public: ByteCodeRegisterIndex m_dstIndex; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { - printf("unary bitwise not r%d <- r%d", (int)m_dstIndex, (int)m_srcIndex); + printf("unary bitwise not r%u <- r%u", m_dstIndex, m_srcIndex); } #endif }; @@ -1480,9 +1480,9 @@ public: AtomicString m_id; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { - printf("unary typeof r%d <- r%d", (int)m_dstIndex, (int)m_srcIndex); + printf("unary typeof r%u <- r%u", m_dstIndex, m_srcIndex); } #endif }; @@ -1505,9 +1505,9 @@ public: AtomicString m_id; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { - printf("unary delete r%d <- r%d r%d %s", (int)m_dstIndex, (int)m_srcIndex0, (int)m_srcIndex1, m_id.string()->toUTF8StringData().data()); + printf("unary delete r%u <- r%u r%u %s", m_dstIndex, m_srcIndex0, m_srcIndex1, m_id.string()->toUTF8StringData().data()); } #endif }; @@ -1527,9 +1527,9 @@ public: ByteCodeRegisterIndex m_dstIndex; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { - printf("template operation(+) r%d <- r%d + r%d", (int)m_dstIndex, (int)m_src0Index, (int)m_src1Index); + printf("template operation(+) r%u <- r%u + r%u", m_dstIndex, m_src0Index, m_src1Index); } #endif }; @@ -1551,9 +1551,9 @@ public: size_t m_jumpPosition; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { - printf("jump %d", dumpJumpPosition(m_jumpPosition, byteCodeStart)); + printf("jump %zu", dumpJumpPosition(m_jumpPosition)); } #endif }; @@ -1674,7 +1674,7 @@ public: size_t m_recordIndex; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { printf("jump complex"); } @@ -1700,9 +1700,9 @@ public: ByteCodeRegisterIndex m_registerIndex; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { - printf("jump if r%d is true -> %d", (int)m_registerIndex, dumpJumpPosition(m_jumpPosition, byteCodeStart)); + printf("jump if r%u is true -> %zu", m_registerIndex, dumpJumpPosition(m_jumpPosition)); } #endif }; @@ -1727,12 +1727,12 @@ public: ByteCodeRegisterIndex m_registerIndex; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { if (m_shouldNegate) { - printf("jump if r%d is not undefined nor null -> %d", (int)m_registerIndex, dumpJumpPosition(m_jumpPosition, byteCodeStart)); + printf("jump if r%u is not undefined nor null -> %zu", m_registerIndex, dumpJumpPosition(m_jumpPosition)); } else { - printf("jump if r%d is undefined or null -> %d", (int)m_registerIndex, dumpJumpPosition(m_jumpPosition, byteCodeStart)); + printf("jump if r%u is undefined or null -> %zu", m_registerIndex, dumpJumpPosition(m_jumpPosition)); } } #endif @@ -1749,9 +1749,9 @@ public: ByteCodeRegisterIndex m_registerIndex; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { - printf("jump if r%d is false -> %d", (int)m_registerIndex, dumpJumpPosition(m_jumpPosition, byteCodeStart)); + printf("jump if r%u is false -> %zu", m_registerIndex, dumpJumpPosition(m_jumpPosition)); } #endif }; @@ -1774,7 +1774,7 @@ public: bool m_switched; // left and right operands are switched #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { char* op; if (m_switched) { @@ -1790,7 +1790,7 @@ public: op = (char*)"less than"; } } - printf("jump if r%d is not %s r%d -> %d", (int)m_leftIndex, op, (int)m_rightIndex, dumpJumpPosition(m_jumpPosition, byteCodeStart)); + printf("jump if r%u is not %s r%u -> %zu", m_leftIndex, op, m_rightIndex, dumpJumpPosition(m_jumpPosition)); } #endif }; @@ -1812,7 +1812,7 @@ public: bool m_shouldNegate; // condition should meet NOT EQUAL #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { char* op; if (m_isStrict) { @@ -1828,7 +1828,7 @@ public: op = (char*)"equal"; } } - printf("jump if r%d is %s to r%d -> %d", (int)m_registerIndex0, op, (int)m_registerIndex1, dumpJumpPosition(m_jumpPosition, byteCodeStart)); + printf("jump if r%u is %s to r%u -> %zu", m_registerIndex0, op, m_registerIndex1, dumpJumpPosition(m_jumpPosition)); } #endif }; @@ -1849,9 +1849,9 @@ public: uint16_t m_argumentCount; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { - printf("call r%d <- r%d(r%d-r%d)", (int)m_resultIndex, (int)m_calleeIndex, (int)m_argumentsStartIndex, (int)m_argumentsStartIndex + (int)m_argumentCount); + printf("call r%u <- r%u(r%u-r%u)", m_resultIndex, m_calleeIndex, m_argumentsStartIndex, m_argumentsStartIndex + m_argumentCount); } #endif }; @@ -1875,9 +1875,9 @@ public: uint16_t m_argumentCount; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { - printf("call r%d <- r%d,r%d(r%d-r%d)", (int)m_resultIndex, (int)m_receiverIndex, (int)m_calleeIndex, (int)m_argumentsStartIndex, (int)m_argumentsStartIndex + (int)m_argumentCount); + printf("call r%u <- r%u,r%u(r%u-r%u)", m_resultIndex, m_receiverIndex, m_calleeIndex, m_argumentsStartIndex, m_argumentsStartIndex + m_argumentCount); } #endif }; @@ -1941,15 +1941,15 @@ public: ByteCodeRegisterIndex m_resultIndex; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { if (m_kind == Kind::InWithScope) { - printf("call(complex inWith) r%d <- %s(r%d-r%d)", (int)m_resultIndex, m_calleeName.string()->toNonGCUTF8StringData().data(), (int)m_argumentsStartIndex, (int)m_argumentsStartIndex + (int)m_argumentCount); + printf("call(complex inWith) r%u <- %s(r%u-r%u)", m_resultIndex, m_calleeName.string()->toNonGCUTF8StringData().data(), m_argumentsStartIndex, m_argumentsStartIndex + m_argumentCount); } else { if (m_receiverOrThisIndex != REGISTER_LIMIT) { - printf("call(complex %d) r%d <- r%d,r%d(r%d-r%d)", (int)m_kind, (int)m_resultIndex, (int)m_receiverOrThisIndex, (int)m_calleeIndex, (int)m_argumentsStartIndex, (int)m_argumentsStartIndex + (int)m_argumentCount); + printf("call(complex %u) r%u <- r%u,r%u(r%u-r%u)", m_kind, m_resultIndex, m_receiverOrThisIndex, m_calleeIndex, m_argumentsStartIndex, m_argumentsStartIndex + m_argumentCount); } else { - printf("call(complex %d) r%d <- r%d(r%d-r%d)", (int)m_kind, (int)m_resultIndex, (int)m_calleeIndex, (int)m_argumentsStartIndex, (int)m_argumentsStartIndex + (int)m_argumentCount); + printf("call(complex %u) r%u <- r%u(r%u-r%u)", m_kind, m_resultIndex, m_calleeIndex, m_argumentsStartIndex, m_argumentsStartIndex + m_argumentCount); } } } @@ -1971,7 +1971,7 @@ public: ExecutionPauser* m_pauser; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { printf("execution resume"); } @@ -2034,14 +2034,14 @@ public: }; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { printf("execution pause "); if (m_reason == Reason::Yield) { - printf("yield r%d r%d r%d", (int)m_yieldData.m_yieldIndex, (int)m_yieldData.m_dstIndex, (int)m_yieldData.m_dstStateIndex); + printf("yield r%u r%u r%u", m_yieldData.m_yieldIndex, m_yieldData.m_dstIndex, m_yieldData.m_dstStateIndex); } else if (m_reason == Reason::Await) { - printf("await r%d r%d r%d", (int)m_awaitData.m_awaitIndex, (int)m_awaitData.m_dstIndex, (int)m_awaitData.m_dstStateIndex); + printf("await r%u r%u r%u", m_awaitData.m_awaitIndex, m_awaitData.m_dstIndex, m_awaitData.m_dstStateIndex); } else if (m_reason == Reason::GeneratorsInitialize) { printf("generators initialize "); } @@ -2065,9 +2065,9 @@ public: uint16_t m_argumentCount; ByteCodeRegisterIndex m_resultIndex; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { - printf("new r%d <- r%d(r%d-r%d)", (int)m_resultIndex, (int)m_calleeIndex, (int)m_argumentsStartIndex, (int)m_argumentsStartIndex + (int)m_argumentCount); + printf("new r%u <- r%u(r%u-r%u)", m_resultIndex, m_calleeIndex, m_argumentsStartIndex, m_argumentsStartIndex + m_argumentCount); } #endif }; @@ -2088,9 +2088,9 @@ public: uint16_t m_argumentCount; ByteCodeRegisterIndex m_resultIndex; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { - printf("new(spread) r%d <- r%d(r%d-r%d)", (int)m_resultIndex, (int)m_calleeIndex, (int)m_argumentsStartIndex, (int)m_argumentsStartIndex + (int)m_argumentCount); + printf("new(spread) r%u <- r%u(r%u-r%u)", m_resultIndex, m_calleeIndex, m_argumentsStartIndex, m_argumentsStartIndex + m_argumentCount); } #endif }; @@ -2107,9 +2107,9 @@ public: ByteCodeRegisterIndex m_registerIndex; uint16_t m_paramIndex; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { - printf("get parameter r%d <- argv[%d]", (int)m_registerIndex, (int)m_paramIndex); + printf("get parameter r%u <- argv[%u]", m_registerIndex, m_paramIndex); } #endif }; @@ -2124,9 +2124,9 @@ public: ByteCodeRegisterIndex m_registerIndex; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { - printf("return r%d", (int)m_registerIndex); + printf("return r%u", m_registerIndex); } #endif }; @@ -2151,9 +2151,9 @@ public: size_t m_tryCatchEndPosition; size_t m_finallyEndPosition; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { - printf("try (hasCatch:%d, save catched value to:r%d, hasFinalizer:%d)", (int)m_hasCatch, (int)m_catchedValueRegisterIndex, (int)m_hasFinalizer); + printf("try (hasCatch:%u, save catched value to:r%u, hasFinalizer:%u)", m_hasCatch, m_catchedValueRegisterIndex, m_hasFinalizer); } #endif }; @@ -2166,7 +2166,7 @@ public: } #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { printf("close lexical environment"); } @@ -2183,9 +2183,9 @@ public: ByteCodeRegisterIndex m_registerIndex; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { - printf("throw r%d", (int)m_registerIndex); + printf("throw r%u", m_registerIndex); } #endif }; @@ -2204,7 +2204,7 @@ public: AtomicString m_templateDataString; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { printf("throw static error %s", m_errorMessage); } @@ -2234,9 +2234,9 @@ public: bool m_isDestruction : 1; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { - printf("create enumerate object r%d <- r%d", (int)m_dataRegisterIndex, (int)m_objectRegisterIndex); + printf("create enumerate object r%u <- r%u", m_dataRegisterIndex, m_objectRegisterIndex); } #endif }; @@ -2258,9 +2258,9 @@ public: ByteCodeRegisterIndex m_dataRegisterIndex; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { - printf("get enumerate key r%d r%d", (int)m_registerIndex, (int)m_dataRegisterIndex); + printf("get enumerate key r%u r%u", m_registerIndex, m_dataRegisterIndex); } #endif }; @@ -2276,9 +2276,9 @@ public: ByteCodeRegisterIndex m_registerIndex; size_t m_exitPosition; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { - printf("check if key is last r%d", (int)m_registerIndex); + printf("check if key is last r%u", m_registerIndex); } #endif }; @@ -2294,9 +2294,9 @@ public: ByteCodeRegisterIndex m_dataRegisterIndex; ByteCodeRegisterIndex m_keyRegisterIndex; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { - printf("mark enumerate key r%d to enumerate object r%d", (int)m_keyRegisterIndex, (int)m_dataRegisterIndex); + printf("mark enumerate key r%u to enumerate object r%u", m_keyRegisterIndex, m_dataRegisterIndex); } #endif }; @@ -2420,24 +2420,24 @@ public: } #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { if (m_operation == Operation::GetIterator) { - printf("get iterator(r%d) -> r%d", (int)m_getIteratorData.m_srcObjectRegisterIndex, (int)m_getIteratorData.m_dstIteratorRecordIndex); + printf("get iterator(r%u) -> r%u", m_getIteratorData.m_srcObjectRegisterIndex, m_getIteratorData.m_dstIteratorRecordIndex); } else if (m_operation == Operation::IteratorClose) { - printf("iterator close(r%d, r%d)", (int)m_iteratorCloseData.m_iterRegisterIndex, (int)m_iteratorCloseData.m_execeptionRegisterIndexIfExists); + printf("iterator close(r%u, r%u)", m_iteratorCloseData.m_iterRegisterIndex, m_iteratorCloseData.m_execeptionRegisterIndexIfExists); } else if (m_operation == Operation::IteratorBind) { - printf("iterator bind(r%d) -> r%d", (int)m_iteratorBindData.m_iterRegisterIndex, (int)m_iteratorBindData.m_registerIndex); + printf("iterator bind(r%u) -> r%u", m_iteratorBindData.m_iterRegisterIndex, m_iteratorBindData.m_registerIndex); } else if (m_operation == Operation::IteratorTestDone) { - printf("iterator test done iteratorRecord(%d)->m_done -> r%d", (int)m_iteratorTestDoneData.m_iteratorRecordOrObjectRegisterIndex, - (int)m_iteratorTestDoneData.m_dstRegisterIndex); + printf("iterator test done iteratorRecord(%u)->m_done -> r%u", m_iteratorTestDoneData.m_iteratorRecordOrObjectRegisterIndex, + m_iteratorTestDoneData.m_dstRegisterIndex); } else if (m_operation == Operation::IteratorNext) { - printf("iterator next r%d.[[next]](r%d) -> r%d", (int)m_iteratorNextData.m_iteratorRecordRegisterIndex, - (int)m_iteratorNextData.m_valueRegisterIndex, (int)m_iteratorNextData.m_returnRegisterIndex); + printf("iterator next r%u.[[next]](r%u) -> r%u", m_iteratorNextData.m_iteratorRecordRegisterIndex, + m_iteratorNextData.m_valueRegisterIndex, m_iteratorNextData.m_returnRegisterIndex); } else if (m_operation == Operation::IteratorTestResultIsObject) { - printf("iterator test result is object r%d", (int)m_iteratorTestResultIsObjectData.m_valueRegisterIndex); + printf("iterator test result is object r%u", m_iteratorTestResultIsObjectData.m_valueRegisterIndex); } else if (m_operation == Operation::IteratorValue) { - printf("iterator value r%d -> r%d", (int)m_iteratorValueData.m_srcRegisterIndex, (int)m_iteratorValueData.m_dstRegisterIndex); + printf("iterator value r%u -> r%u", m_iteratorValueData.m_srcRegisterIndex, m_iteratorValueData.m_dstRegisterIndex); } else if (m_operation == Operation::IteratorCheckOngoingExceptionOnAsyncIteratorClose) { printf("iterator check ongoing exception"); } else { @@ -2475,9 +2475,9 @@ public: AtomicString m_propertyName; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { - printf("get method r%d.%s -> r%d", (int)m_objectRegisterIndex, m_propertyName.string()->toNonGCUTF8StringData().data(), (int)m_resultRegisterIndex); + printf("get method r%u.%s -> r%u", m_objectRegisterIndex, m_propertyName.string()->toNonGCUTF8StringData().data(), m_resultRegisterIndex); } #endif }; @@ -2496,9 +2496,9 @@ public: String* m_body; String* m_option; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { - printf("load regexp %s -> r%d", m_body->toUTF8StringData().data(), (int)m_registerIndex); + printf("load regexp %s -> r%u", m_body->toUTF8StringData().data(), m_registerIndex); } #endif }; @@ -2521,9 +2521,9 @@ public: ByteCodeRegisterIndex m_withOrThisRegisterIndex : 16; size_t m_endPostion; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { - printf("open lexical env r%d(%d)", (int)m_withOrThisRegisterIndex, (int)m_kind); + printf("open lexical env r%u(%u)", m_withOrThisRegisterIndex, m_kind); } #endif }; @@ -2547,12 +2547,12 @@ public: bool m_isGetter : 1; // other case, this is setter #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { if (m_isGetter) { - printf("object define getter r%d[r%d] = r%d", (int)m_objectRegisterIndex, (int)m_objectPropertyNameRegisterIndex, (int)m_objectPropertyValueRegisterIndex); + printf("object define getter r%u[r%u] = r%u", m_objectRegisterIndex, m_objectPropertyNameRegisterIndex, m_objectPropertyValueRegisterIndex); } else { - printf("object define setter r%d[r%d] = r%d", (int)m_objectRegisterIndex, (int)m_objectPropertyNameRegisterIndex, (int)m_objectPropertyValueRegisterIndex); + printf("object define setter r%u[r%u] = r%u", m_objectRegisterIndex, m_objectPropertyNameRegisterIndex, m_objectPropertyValueRegisterIndex); } } #endif @@ -2572,9 +2572,9 @@ public: ByteCodeRegisterIndex m_iterOrEnumIndex; ByteCodeRegisterIndex m_dstIndex; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { - printf("binding rest element(r%d) -> r%d", (int)m_iterOrEnumIndex, (int)m_dstIndex); + printf("binding rest element(r%u) -> r%u", m_iterOrEnumIndex, m_dstIndex); } #endif }; @@ -2591,9 +2591,9 @@ public: size_t m_blockEndPosition; InterpretedCodeBlock::BlockInfo* m_blockInfo; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { - printf("block operation (%p) -> end %d", m_blockInfo, (int)m_blockEndPosition); + printf("block operation (%p) -> end %zu", m_blockInfo, m_blockEndPosition); } #endif }; @@ -2608,7 +2608,7 @@ public: InterpretedCodeBlock::BlockInfo* m_blockInfo; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { printf("replace block lexical env operation (%p)", m_blockInfo); } @@ -2653,12 +2653,12 @@ public: }; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { if (m_operaton == TestCacheOperation) { - printf("tagged template operation operation (test cache %d)", (int)m_testCacheOperationData.m_cacheIndex); + printf("tagged template operation operation (test cache %zu)", m_testCacheOperationData.m_cacheIndex); } else { - printf("tagged template operation operation (fill cache %d)", (int)m_testCacheOperationData.m_cacheIndex); + printf("tagged template operation operation (fill cache %zu)", m_testCacheOperationData.m_cacheIndex); } } #endif @@ -2672,7 +2672,7 @@ public: } #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { printf("ensure arguments object"); } @@ -2689,9 +2689,9 @@ public: } #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { - printf("r%d <- resolve name address (%s)", (int)m_registerIndex, m_name.string()->toNonGCUTF8StringData().data()); + printf("r%u <- resolve name address (%s)", m_registerIndex, m_name.string()->toNonGCUTF8StringData().data()); } #endif @@ -2713,9 +2713,9 @@ public: AtomicString m_name; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { - printf("store with address r%d, %s <- r%d", (int)m_addressRegisterIndex, m_name.string()->toUTF8StringData().data(), (int)m_valueRegisterIndex); + printf("store with address r%u, %s <- r%u", m_addressRegisterIndex, m_name.string()->toUTF8StringData().data(), m_valueRegisterIndex); } #endif }; @@ -2730,9 +2730,9 @@ public: ByteCodeRegisterIndex m_registerIndex; #ifndef NDEBUG - void dump(const char* byteCodeStart) + void dump() { - printf("end(return with r[%d])", (int)m_registerIndex); + printf("end(return with r[%u])", m_registerIndex); } #endif }; diff --git a/lwnode/code/escargotshim/deps/escargot/src/interpreter/ByteCodeGenerator.cpp b/lwnode/code/escargotshim/deps/escargot/src/interpreter/ByteCodeGenerator.cpp index 7d90161..27ee6be 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/interpreter/ByteCodeGenerator.cpp +++ b/lwnode/code/escargotshim/deps/escargot/src/interpreter/ByteCodeGenerator.cpp @@ -835,31 +835,7 @@ void ByteCodeGenerator::printByteCode(Context* context, ByteCodeBlock* block) } printf("]\n"); - - char* code = block->m_code.data(); - size_t idx = 0; - size_t end = block->m_code.size(); - - while (idx < end) { - ByteCode* currentCode = (ByteCode*)(code + idx); - - currentCode->dumpCode(idx, (const char*)code); - - if (currentCode->m_orgOpcode == ExecutionPauseOpcode) { - if (((ExecutionPause*)currentCode)->m_reason == ExecutionPause::Yield) { - idx += ((ExecutionPause*)currentCode)->m_yieldData.m_tailDataLength; - } else if (((ExecutionPause*)currentCode)->m_reason == ExecutionPause::Await) { - idx += ((ExecutionPause*)currentCode)->m_awaitData.m_tailDataLength; - } else if (((ExecutionPause*)currentCode)->m_reason == ExecutionPause::GeneratorsInitialize) { - idx += ((ExecutionPause*)currentCode)->m_asyncGeneratorInitializeData.m_tailDataLength; - } else { - ASSERT_NOT_REACHED(); - } - } - - idx += byteCodeLengths[currentCode->m_orgOpcode]; - } - + ByteCode::dumpCode(block->m_code.data(), block->m_code.size()); printf("dumpBytecode...<<<<<<<<<<<<<<<<<<<<<<\n"); } } diff --git a/lwnode/code/escargotshim/deps/escargot/src/interpreter/ByteCodeInterpreter.cpp b/lwnode/code/escargotshim/deps/escargot/src/interpreter/ByteCodeInterpreter.cpp index 22952e7..38feaa9 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/interpreter/ByteCodeInterpreter.cpp +++ b/lwnode/code/escargotshim/deps/escargot/src/interpreter/ByteCodeInterpreter.cpp @@ -3784,7 +3784,7 @@ NEVER_INLINE void ByteCodeInterpreter::defineObjectGetterSetter(ExecutionState& } ObjectPropertyDescriptor desc(*gs, code->m_presentAttribute); Object* object = registerFile[code->m_objectRegisterIndex].toObject(state); - object->defineOwnPropertyThrowsExceptionWhenStrictMode(state, ObjectPropertyName(state, pName), desc); + object->defineOwnPropertyThrowsException(state, ObjectPropertyName(state, pName), desc); } ALWAYS_INLINE Value ByteCodeInterpreter::incrementOperation(ExecutionState& state, const Value& value) diff --git a/lwnode/code/escargotshim/deps/escargot/src/intl/Intl.cpp b/lwnode/code/escargotshim/deps/escargot/src/intl/Intl.cpp index c7e236a..fda957f 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/intl/Intl.cpp +++ b/lwnode/code/escargotshim/deps/escargot/src/intl/Intl.cpp @@ -116,39 +116,60 @@ static std::string grandfatheredLangTag(const std::string& locale) static std::string intlPreferredLanguageTag(const std::string& tag) { - // 78 possible replacements + // languageAlias element in + // https://www.unicode.org/repos/cldr/trunk/common/supplemental/supplementalMetadata.xml + if (tag == "cmn") + return "zh"; + if (tag == "ces") + return "cs"; + if (tag == "heb") + return "he"; + if (tag == "xsj") + return "suj"; if (tag == "aar") return "aa"; + + // legacy + if (tag == "tl") + return "fil"; + + // 92 possible replacements if (tag == "aam") return "aas"; if (tag == "adp") return "dz"; + if (tag == "asd") + return "snz"; if (tag == "aue") return "ktz"; if (tag == "ayx") return "nun"; if (tag == "bgm") return "bcg"; + if (tag == "bic") + return "bir"; if (tag == "bjd") return "drl"; + if (tag == "blg") + return "iba"; if (tag == "ccq") return "rki"; - if (tag == "ces") - return "cs"; if (tag == "cjr") return "mom"; if (tag == "cka") return "cmr"; if (tag == "cmk") return "xch"; - if (tag == "cmn") - return "zh"; if (tag == "coy") return "pij"; if (tag == "cqu") return "quh"; + if (tag == "dit") + return "dif"; if (tag == "drh") return "khk"; + if (tag == "drr") + return "kzk"; if (tag == "drw") return "prs"; if (tag == "gav") @@ -157,12 +178,12 @@ static std::string intlPreferredLanguageTag(const std::string& tag) return "vaj"; if (tag == "ggn") return "gvr"; + if (tag == "gli") + return "kzk"; if (tag == "gti") return "nyc"; if (tag == "guv") return "duz"; - if (tag == "heb") - return "he"; if (tag == "hrr") return "jal"; if (tag == "ibi") @@ -195,12 +216,16 @@ static std::string intlPreferredLanguageTag(const std::string& tag) return "yam"; if (tag == "kxe") return "tvd"; + if (tag == "kxl") + return "kru"; if (tag == "kzj") return "dtp"; if (tag == "kzt") return "dtp"; if (tag == "lii") return "raq"; + if (tag == "llo") + return "ngt"; if (tag == "lmm") return "rmx"; if (tag == "meg") @@ -211,18 +236,26 @@ static std::string intlPreferredLanguageTag(const std::string& tag) return "mry"; if (tag == "mwj") return "vaj"; + if (tag == "myd") + return "aog"; if (tag == "myt") return "mry"; if (tag == "nad") return "xny"; if (tag == "ncp") return "kdz"; + if (tag == "nns") + return "nbr"; if (tag == "nnx") return "ngv"; if (tag == "nts") return "pij"; + if (tag == "nxu") + return "bpp"; if (tag == "oun") return "vaj"; + if (tag == "pat") + return "kxr"; if (tag == "pcr") return "adx"; if (tag == "pmc") @@ -245,6 +278,8 @@ static std::string intlPreferredLanguageTag(const std::string& tag) return "dtp"; if (tag == "thc") return "tpo"; + if (tag == "thw") + return "ola"; if (tag == "thx") return "oyb"; if (tag == "tie") @@ -269,8 +304,8 @@ static std::string intlPreferredLanguageTag(const std::string& tag) return "acn"; if (tag == "xkh") return "waw"; - if (tag == "xsj") - return "suj"; + if (tag == "xrq") + return "dmw"; if (tag == "ybd") return "rki"; if (tag == "yma") @@ -281,16 +316,20 @@ static std::string intlPreferredLanguageTag(const std::string& tag) return "zom"; if (tag == "yuu") return "yug"; + if (tag == "zir") + return "scv"; return ""; } static std::string intlRedundantLanguageTag(const std::string& tag) { - // 24 possible replacements + // non-iana if (tag == "hy-arevela") return "hy"; if (tag == "hy-arevmda") return "hyw"; + + // 24 possible replacements if (tag == "ja-Latn-hepburn-heploc") return "ja-Latn-alalc97"; if (tag == "sgn-BR") @@ -307,8 +346,8 @@ static std::string intlRedundantLanguageTag(const std::string& tag) return "fsl"; if (tag == "sgn-GB") return "bfi"; - if (tag == "gss") - return "sgn-GR"; + if (tag == "sgn-GR") + return "gss"; if (tag == "sgn-IE") return "isg"; if (tag == "sgn-IT") @@ -349,7 +388,7 @@ std::string Intl::preferredLanguage(const std::string& language) static std::string intlPreferredExtlangTag(const std::string& tag) { - // 235 possible replacements + // 245 possible replacements if (tag == "aao") return "ar"; if (tag == "abh") @@ -452,6 +491,8 @@ static std::string intlPreferredExtlangTag(const std::string& tag) return "zh"; if (tag == "cmn") return "zh"; + if (tag == "cnp") + return "zh"; if (tag == "coa") return "ms"; if (tag == "cpx") @@ -470,10 +511,14 @@ static std::string intlPreferredExtlangTag(const std::string& tag) return "sgn"; if (tag == "csn") return "sgn"; + if (tag == "csp") + return "zh"; if (tag == "csq") return "sgn"; if (tag == "csr") return "sgn"; + if (tag == "csx") + return "sgn"; if (tag == "czh") return "zh"; if (tag == "czo") @@ -488,6 +533,8 @@ static std::string intlPreferredExtlangTag(const std::string& tag) return "ms"; if (tag == "ecs") return "sgn"; + if (tag == "ehs") + return "sgn"; if (tag == "esl") return "sgn"; if (tag == "esn") @@ -566,6 +613,8 @@ static std::string intlPreferredExtlangTag(const std::string& tag) return "sgn"; if (tag == "jhs") return "sgn"; + if (tag == "jks") + return "sgn"; if (tag == "jls") return "sgn"; if (tag == "jos") @@ -596,16 +645,22 @@ static std::string intlPreferredExtlangTag(const std::string& tag) return "ms"; if (tag == "lls") return "sgn"; + if (tag == "lsb") + return "sgn"; if (tag == "lsg") return "sgn"; if (tag == "lsl") return "sgn"; + if (tag == "lsn") + return "sgn"; if (tag == "lso") return "sgn"; if (tag == "lsp") return "sgn"; if (tag == "lst") return "sgn"; + if (tag == "lsv") + return "sgn"; if (tag == "lsy") return "sgn"; if (tag == "ltg") @@ -730,6 +785,8 @@ static std::string intlPreferredExtlangTag(const std::string& tag) return "sgn"; if (tag == "sqs") return "sgn"; + if (tag == "sqx") + return "sgn"; if (tag == "ssh") return "ar"; if (tag == "ssp") @@ -808,6 +865,8 @@ static std::string intlPreferredExtlangTag(const std::string& tag) return "sgn"; if (tag == "ysl") return "sgn"; + if (tag == "ysm") + return "sgn"; if (tag == "yue") return "zh"; if (tag == "zib") @@ -924,6 +983,21 @@ Intl::CanonicalizedLangunageTag Intl::canonicalizeLanguageTag(const std::string& std::transform(language.begin(), language.end(), language.begin(), tolower); result.language = language; language = Intl::preferredLanguage(language); + + // test legacy cases + // https://github.com/unicode-org/cldr/blob/master/common/supplemental/supplementalMetadata.xml + if (result.language == "sh") { + language = result.language = "sr"; + if (!result.script.length()) { + result.script = "Latn"; + } + } else if (result.language == "cnr") { + language = result.language = "sr"; + if (!result.region.length()) { + result.region = "ME"; + } + } + canonical.appendString(String::fromUTF8(language.data(), language.length())); // Check for extlang. @@ -951,6 +1025,7 @@ Intl::CanonicalizedLangunageTag Intl::canonicalizeLanguageTag(const std::string& // Check for script. // script = 4ALPHA + bool isScriptAddToCanonical = false; if (currentIndex < numParts) { std::string script = parts[currentIndex]; unsigned scriptLength = script.length(); @@ -963,11 +1038,18 @@ Intl::CanonicalizedLangunageTag Intl::canonicalizeLanguageTag(const std::string& script = script.substr(1, 3); result.script += script; canonical.appendString(String::fromUTF8(script.data(), script.length())); + isScriptAddToCanonical = true; } } + if (!isScriptAddToCanonical && result.script.length()) { + canonical.appendString("-"); + canonical.appendString(String::fromUTF8(result.script.data(), result.script.length())); + } + // Check for region. // region = 2ALPHA / 3DIGIT + bool isRegionAddToCanonical = false; if (currentIndex < numParts) { std::string region = parts[currentIndex]; unsigned regionLength = region.length(); @@ -980,9 +1062,15 @@ Intl::CanonicalizedLangunageTag Intl::canonicalizeLanguageTag(const std::string& result.region = region; auto preffered = preferredRegion(region); canonical.appendString(String::fromUTF8(preffered.data(), preffered.length())); + isRegionAddToCanonical = true; } } + if (!isRegionAddToCanonical && result.region.length()) { + canonical.appendString("-"); + canonical.appendString(String::fromUTF8(result.region.data(), result.region.length())); + } + // Check for variant. // variant = 5*8alphanum / (DIGIT 3alphanum) std::unordered_set subtags; @@ -1808,6 +1896,33 @@ Value Intl::getOption(ExecutionState& state, Object* options, Value property, In } } +template +T Intl::getNumberOption(ExecutionState& state, Object* options, String* property, double minimum, double maximum, const T& fallback) +{ + // http://www.ecma-international.org/ecma-402/1.0/index.html#sec-9.2.10 + + // Let value be the result of calling the [[Get]] internal method of options with argument property. + Value value = options->get(state, ObjectPropertyName(state, property)).value(state, options); + // If value is not undefined, then + if (!value.isUndefined()) { + // Let value be ToNumber(value). + double doubleValue = value.toNumber(state); + // If value is NaN or less than minimum or greater than maximum, throw a RangeError exception. + if (std::isnan(doubleValue) || doubleValue < minimum || maximum < doubleValue) { + ErrorObject::throwBuiltinError(state, ErrorObject::RangeError, "Got invalid number option value"); + } + // Return floor(value). + return T(floor(doubleValue)); + } else { + // Else return fallback. + return fallback; + } +} + +template Value Intl::getNumberOption(ExecutionState& state, Object* options, String* property, double minimum, double maximum, const Value& fallback); +template double Intl::getNumberOption(ExecutionState& state, Object* options, String* property, double minimum, double maximum, const double& fallback); +template int Intl::getNumberOption(ExecutionState& state, Object* options, String* property, double minimum, double maximum, const int& fallback); + static std::vector initAvailableNumberingSystems() { std::vector availableNumberingSystems; diff --git a/lwnode/code/escargotshim/deps/escargot/src/intl/Intl.h b/lwnode/code/escargotshim/deps/escargot/src/intl/Intl.h index 595bdce..020d2e1 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/intl/Intl.h +++ b/lwnode/code/escargotshim/deps/escargot/src/intl/Intl.h @@ -47,6 +47,8 @@ public: BooleanValue }; static Value getOption(ExecutionState& state, Object* options, Value property, OptionValueType type, Value* values, size_t valuesLength, const Value& fallback); + template + static T getNumberOption(ExecutionState& state, Object* options, String* property, double minimum, double maximum, const T& fallback); static std::string preferredLanguage(const std::string& language); static String* icuLocaleToBCP47Tag(String* string); static std::vector calendarsForLocale(String* locale); diff --git a/lwnode/code/escargotshim/deps/escargot/src/intl/IntlDateTimeFormat.cpp b/lwnode/code/escargotshim/deps/escargot/src/intl/IntlDateTimeFormat.cpp index 3c0926a..0551119 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/intl/IntlDateTimeFormat.cpp +++ b/lwnode/code/escargotshim/deps/escargot/src/intl/IntlDateTimeFormat.cpp @@ -61,6 +61,7 @@ static const size_t indexOfExtensionKeyCa = 0; static const size_t indexOfExtensionKeyNu = 1; static const size_t indexOfExtensionKeyHc = 2; static const double minECMAScriptTime = -8.64E15; +static const size_t defaultStringBufferSize = 32; std::vector Intl::calendarsForLocale(String* locale) { @@ -196,13 +197,6 @@ static String* defaultTimeZone(ExecutionState& state) return String::fromUTF8(state.context()->vmInstance()->timezoneID().data(), state.context()->vmInstance()->timezoneID().length()); } -Object* IntlDateTimeFormat::create(ExecutionState& state, Context* realm, Value locales, Value options) -{ - Object* dateTimeFormat = new Object(state, realm->globalObject()->intlDateTimeFormatPrototype()); - initialize(state, dateTimeFormat, locales, options); - return dateTimeFormat; -} - static std::string readHourCycleFromPattern(const UTF16StringDataNonGCStd& patternString) { bool inQuote = false; @@ -275,34 +269,77 @@ UTF16StringDataNonGCStd updateHourCycleInPatternDueToHourCycle(const UTF16String } -void IntlDateTimeFormat::initialize(ExecutionState& state, Object* dateTimeFormat, Value locales, Value options) +static String* icuFieldTypeToPartName(ExecutionState& state, int32_t fieldName) { - // If dateTimeFormat has an [[initializedIntlObject]] internal property with value true, throw a TypeError exception. - AtomicString initializedIntlObject = state.context()->staticStrings().lazyInitializedIntlObject(); - if (dateTimeFormat->hasInternalSlot() && dateTimeFormat->internalSlot()->hasOwnProperty(state, ObjectPropertyName(state, ObjectStructurePropertyName(initializedIntlObject)))) { - ErrorObject::throwBuiltinError(state, ErrorObject::TypeError, "Cannot initialize Intl Object twice"); + if (fieldName == -1) { + return state.context()->staticStrings().lazyLiteral().string(); } - // Set the [[initializedIntlObject]] internal property of dateTimeFormat to true. - dateTimeFormat->ensureInternalSlot(state)->defineOwnProperty(state, ObjectPropertyName(initializedIntlObject), ObjectPropertyDescriptor(Value(true))); + switch (static_cast(fieldName)) { + case UDAT_ERA_FIELD: + return state.context()->staticStrings().lazyEra().string(); + case UDAT_YEAR_FIELD: + case UDAT_YEAR_WOY_FIELD: + case UDAT_EXTENDED_YEAR_FIELD: + case UDAT_YEAR_NAME_FIELD: + return state.context()->staticStrings().lazyYear().string(); + case UDAT_MONTH_FIELD: + case UDAT_STANDALONE_MONTH_FIELD: + return state.context()->staticStrings().lazyMonth().string(); + case UDAT_DATE_FIELD: + case UDAT_JULIAN_DAY_FIELD: + return state.context()->staticStrings().lazyDay().string(); + case UDAT_HOUR_OF_DAY1_FIELD: + case UDAT_HOUR_OF_DAY0_FIELD: + case UDAT_HOUR1_FIELD: + case UDAT_HOUR0_FIELD: + return state.context()->staticStrings().lazyHour().string(); + case UDAT_MINUTE_FIELD: + return state.context()->staticStrings().lazyMinute().string(); + case UDAT_SECOND_FIELD: + return state.context()->staticStrings().lazySecond().string(); + case UDAT_DAY_OF_WEEK_FIELD: + case UDAT_STANDALONE_DAY_FIELD: + case UDAT_DOW_LOCAL_FIELD: + case UDAT_DAY_OF_WEEK_IN_MONTH_FIELD: + return state.context()->staticStrings().lazyWeekday().string(); + case UDAT_AM_PM_FIELD: + case UDAT_AM_PM_MIDNIGHT_NOON_FIELD: + case UDAT_FLEXIBLE_DAY_PERIOD_FIELD: + return state.context()->staticStrings().lazyDayPeriod().string(); + case UDAT_TIMEZONE_FIELD: + return state.context()->staticStrings().lazyTimeZoneName().string(); + case UDAT_FRACTIONAL_SECOND_FIELD: + return state.context()->staticStrings().lazyFractionalSecond().string(); + default: + ASSERT_NOT_REACHED(); + return String::emptyString; + } +} - // Let requestedLocales be the result of calling the - // CanonicalizeLocaleList abstract operation (defined in 9.2.1) with argument locales. - ValueVector requestedLocales = Intl::canonicalizeLocaleList(state, locales); +IntlDateTimeFormatObject::IntlDateTimeFormatObject(ExecutionState& state, Value locales, Value options) + : IntlDateTimeFormatObject(state, state.context()->globalObject()->intlDateTimeFormatPrototype(), locales, options) +{ +} - // Let options be the result of calling the ToDateTimeOptions abstract operation (defined below) with arguments options, "any", and "date". +IntlDateTimeFormatObject::IntlDateTimeFormatObject(ExecutionState& state, Object* proto, Value locales, Value options) + : Object(state, proto) + , m_locale(String::emptyString) + , m_calendar(String::emptyString) + , m_numberingSystem(String::emptyString) + , m_timeZone(String::emptyString) +{ + // Let requestedLocales be ? CanonicalizeLocaleList(locales). + ValueVector requestedLocales = Intl::canonicalizeLocaleList(state, locales); + // Let options be ? ToDateTimeOptions(options, "any", "date"). options = toDateTimeOptions(state, options, state.context()->staticStrings().lazyAny().string(), state.context()->staticStrings().lazyDate().string()); - // Let opt be a new Record. StringMap opt; - // Let matcher be the result of calling the GetOption abstract operation (defined in 9.2.9) with arguments options, - // "localeMatcher", "string", a List containing the two String values "lookup" and "best fit", and "best fit". + // Let matcher be ? GetOption(options, "localeMatcher", "string", « "lookup", "best fit" », "best fit"). + // Set opt.[[localeMatcher]] to matcher. Value matcherValues[2] = { state.context()->staticStrings().lazyLookup().string(), state.context()->staticStrings().lazyBestFit().string() }; Value matcher = Intl::getOption(state, options.asObject(), state.context()->staticStrings().lazyLocaleMatcher().string(), Intl::StringValue, matcherValues, 2, matcherValues[1]); - // Set opt.[[localeMatcher]] to matcher. - opt.insert(std::make_pair("localeMatcher", matcher.toString(state))); - // Let calendar be ? GetOption(options, "calendar", "string", undefined, undefined). Value calendar = Intl::getOption(state, options.asObject(), state.context()->staticStrings().calendar.string(), Intl::StringValue, nullptr, 0, Value()); // If calendar is not undefined, then @@ -312,10 +349,12 @@ void IntlDateTimeFormat::initialize(ExecutionState& state, Object* dateTimeForma ErrorObject::throwBuiltinError(state, ErrorObject::RangeError, "The calendar value you gave is not valid"); } } + // Set opt.[[ca]] to calendar. if (!calendar.isUndefined()) { opt.insert(std::make_pair("ca", calendar.toString(state))); } + // Let numberingSystem be ? GetOption(options, "numberingSystem", "string", undefined, undefined). Value numberingSystem = Intl::getOption(state, options.asObject(), state.context()->staticStrings().numberingSystem.string(), Intl::StringValue, nullptr, 0, Value()); // If numberingSystem is not undefined, then @@ -346,12 +385,9 @@ void IntlDateTimeFormat::initialize(ExecutionState& state, Object* dateTimeForma opt.insert(std::make_pair("hc", hourCycle.toString(state))); } - // Let DateTimeFormat be the standard built-in object that is the initial value of Intl.DateTimeFormat. - // Let localeData be the value of the [[localeData]] internal property of DateTimeFormat. + // Let localeData be %DateTimeFormat%.[[LocaleData]]. const auto& availableLocales = state.context()->vmInstance()->intlDateTimeFormatAvailableLocales(); - - // Let r be the result of calling the ResolveLocale abstract operation (defined in 9.2.5) with the - // [[availableLocales]] internal property of DateTimeFormat, requestedLocales, opt, the [[relevantExtensionKeys]] internal property of DateTimeFormat, and localeData. + // Let r be ResolveLocale(%DateTimeFormat%.[[AvailableLocales]], requestedLocales, opt, %DateTimeFormat%.[[RelevantExtensionKeys]], localeData). StringMap r = Intl::resolveLocale(state, availableLocales, requestedLocales, opt, intlDateTimeFormatRelevantExtensionKeys, intlDateTimeFormatRelevantExtensionKeysLength, localeDataDateTimeFormat); // The resolved locale doesn't include a hc Unicode extension value if the hour12 or hourCycle option is also present. @@ -361,80 +397,81 @@ void IntlDateTimeFormat::initialize(ExecutionState& state, Object* dateTimeForma iter->second = Intl::canonicalizeLanguageTag(locale->toNonGCUTF8StringData(), "hc").canonicalizedTag.value(); } - // Set the [[locale]] internal property of dateTimeFormat to the value of r.[[locale]]. - dateTimeFormat->internalSlot()->set(state, ObjectPropertyName(state.context()->staticStrings().lazySmallLetterLocale()), r.at("locale"), dateTimeFormat->internalSlot()); - // Set the [[calendar]] internal property of dateTimeFormat to the value of r.[[ca]]. - dateTimeFormat->internalSlot()->set(state, ObjectPropertyName(state.context()->staticStrings().calendar), r.at("ca"), dateTimeFormat->internalSlot()); - // Set dateTimeFormat.[[hourCycle]] to r.[[hc]]. - dateTimeFormat->internalSlot()->set(state, ObjectPropertyName(state.context()->staticStrings().hourCycle), r.at("hc"), dateTimeFormat->internalSlot()); - // Set the [[numberingSystem]] internal property of dateTimeFormat to the value of r.[[nu]]. - dateTimeFormat->internalSlot()->set(state, ObjectPropertyName(state.context()->staticStrings().numberingSystem), r.at("nu"), dateTimeFormat->internalSlot()); - - // Let dataLocale be the value of r.[[dataLocale]]. + // Set dateTimeFormat.[f[Locale]] to r.[[locale]]. + m_locale = r.at("locale"); + // Let calendar be r.[[ca]]. + calendar = r.at("ca"); + // Set dateTimeFormat.[[Calendar]] to calendar. + m_calendar = calendar.asString(); + // Set dateTimeFormat.[[HourCycle]] to r.[[hc]]. + m_hourCycle = r.at("hc"); + // Set dateTimeFormat.[[NumberingSystem]] to r.[[nu]]. + m_numberingSystem = r.at("nu"); + + // Let dataLocale be r.[[dataLocale]]. Value dataLocale = r.at("dataLocale"); - - // Always use ICU date format generator, rather than our own pattern list and matcher. - UErrorCode status = U_ZERO_ERROR; - LocalResourcePointer generator(udatpg_open(dataLocale.toString(state)->toUTF8StringData().data(), &status), - [](UDateTimePatternGenerator* d) { udatpg_close(d); }); - if (U_FAILURE(status)) { - ErrorObject::throwBuiltinError(state, ErrorObject::TypeError, "failed to initialize DateTimeFormat"); - return; - } - - // Let tz be the result of calling the [[Get]] internal method of options with argument "timeZone". - Value tz = options.asObject()->get(state, ObjectPropertyName(state.context()->staticStrings().lazyTimeZone())).value(state, options.asObject()); - - // If tz is not undefined, then - if (!tz.isUndefined()) { - // Let tz be ToString(tz). - String* tzString = tz.toString(state); - // Convert tz to upper case as described in 6.1. - // NOTE: If an implementation accepts additional time zone values, as permitted under certain conditions by the Conformance clause, - // different casing rules apply., If tz is not "UTC", then throw a RangeError exception. - tz = canonicalizeTimeZoneName(state, tzString); - tzString = tz.toString(state); + std::string dataLocaleWithExtensions = dataLocale.toString(state)->toNonGCUTF8StringData() + "-u-ca-" + m_calendar->toNonGCUTF8StringData() + "-nu-" + m_numberingSystem->toNonGCUTF8StringData(); + + // Let timeZone be ? Get(options, "timeZone"). + Value timeZone = options.asObject()->get(state, state.context()->staticStrings().lazyTimeZone()).value(state, options.asObject()); + // If timeZone is undefined, then + if (timeZone.isUndefined()) { + // Let timeZone be DefaultTimeZone(). + timeZone = defaultTimeZone(state); + } else { + // Else, + // Let timeZone be ? ToString(timeZone). + // If the result of IsValidTimeZoneName(timeZone) is false, then Throw a RangeError exception. + // Let timeZone be CanonicalizeTimeZoneName(timeZone). + String* tzString = timeZone.toString(state); + timeZone = canonicalizeTimeZoneName(state, tzString); + tzString = timeZone.toString(state); if (tzString->length() == 0) { ErrorObject::throwBuiltinError(state, ErrorObject::RangeError, "got invalid timezone value"); } - } else { - tz = defaultTimeZone(state); } - // Set the [[timeZone]] internal property of dateTimeFormat to tz. - dateTimeFormat->internalSlot()->set(state, ObjectPropertyName(state.context()->staticStrings().lazyTimeZone()), tz, dateTimeFormat->internalSlot()); + + // Set dateTimeFormat.[[TimeZone]] to timeZone. + if (!timeZone.isUndefined()) { + m_timeZone = timeZone.asString(); + } // Let opt be a new Record. opt.clear(); - // Table 3 – Components of date and time formats - // Property Values - // weekday "narrow", "short", "long" - // era "narrow", "short", "long" - // year "2-digit", "numeric" - // month "2-digit", "numeric", "narrow", "short", "long" - // day "2-digit", "numeric" - // hour "2-digit", "numeric" - // minute "2-digit", "numeric" - // second "2-digit", "numeric" - // timeZoneName "short", "long" - - // For each row of Table 3, except the header row, do: - std::function doTable3 = [&](String* prop, Value* values, size_t valuesSize) { - // Let prop be the name given in the Property column of the row. - // Let value be the result of calling the GetOption abstract operation, passing as argument options, the name given in the Property column of the row, - // "string", a List containing the strings given in the Values column of the row, and undefined. + // Table 4: Components of date and time formats + // [[Weekday]] "weekday" "narrow", "short", "long" + // [[Era]] "era" "narrow", "short", "long" + // [[Year]] "year" "2-digit", "numeric" + // [[Month]] "month" "2-digit", "numeric", "narrow", "short", "long" + // [[Day]] "day" "2-digit", "numeric" + // [[DayPeriod]] "dayPeriod" "narrow", "short", "long" + // [[Hour]] "hour" "2-digit", "numeric" + // [[Minute]] "minute" "2-digit", "numeric" + // [[Second]] "second" "2-digit", "numeric" + // [[FractionalSecondDigits]] "fractionalSecondDigits" 1𝔽, 2𝔽, 3𝔽 + // [[TimeZoneName]] "timeZoneName" "short", "long" + + std::function doTable4 = [&](String* prop, Value* values, size_t valuesSize) { Value value = Intl::getOption(state, options.asObject(), prop, Intl::StringValue, values, valuesSize, Value()); // Set opt.[[]] to value. if (!value.isUndefined()) { opt.insert(std::make_pair(prop->toNonGCUTF8StringData(), value.toString(state))); } }; - StringBuilder skeletonBuilder; + // For each row of Table 4, except the header row, in table order, do + // Let prop be the name given in the Property column of the row. + // If prop is "fractionalSecondDigits", then + // Let value be ? GetNumberOption(options, "fractionalSecondDigits", 1, 3, undefined). + // Else, + // Let value be ? GetOption(options, prop, "string", « the strings given in the Values column of the row », undefined). + // Set opt.[[]] to value. + Value narrowShortLongValues[3] = { state.context()->staticStrings().lazyNarrow().string(), state.context()->staticStrings().lazyShort().string(), state.context()->staticStrings().lazyLong().string() }; - doTable3(state.context()->staticStrings().lazyWeekday().string(), narrowShortLongValues, 3); + doTable4(state.context()->staticStrings().lazyWeekday().string(), narrowShortLongValues, 3); String* ret = opt.at("weekday"); @@ -446,7 +483,7 @@ void IntlDateTimeFormat::initialize(ExecutionState& state, Object* dateTimeForma skeletonBuilder.appendString("EEEE"); } - doTable3(state.context()->staticStrings().lazyEra().string(), narrowShortLongValues, 3); + doTable4(state.context()->staticStrings().lazyEra().string(), narrowShortLongValues, 3); ret = opt.at("era"); if (ret->equals("narrow")) { @@ -458,7 +495,7 @@ void IntlDateTimeFormat::initialize(ExecutionState& state, Object* dateTimeForma } Value twoDightNumericValues[2] = { state.context()->staticStrings().lazyTwoDigit().string(), state.context()->staticStrings().numeric.string() }; - doTable3(state.context()->staticStrings().lazyYear().string(), twoDightNumericValues, 2); + doTable4(state.context()->staticStrings().lazyYear().string(), twoDightNumericValues, 2); ret = opt.at("year"); if (ret->equals("2-digit")) { @@ -468,7 +505,7 @@ void IntlDateTimeFormat::initialize(ExecutionState& state, Object* dateTimeForma } Value allValues[5] = { state.context()->staticStrings().lazyTwoDigit().string(), state.context()->staticStrings().numeric.string(), state.context()->staticStrings().lazyNarrow().string(), state.context()->staticStrings().lazyShort().string(), state.context()->staticStrings().lazyLong().string() }; - doTable3(state.context()->staticStrings().lazyMonth().string(), allValues, 5); + doTable4(state.context()->staticStrings().lazyMonth().string(), allValues, 5); ret = opt.at("month"); if (ret->equals("2-digit")) { @@ -483,7 +520,7 @@ void IntlDateTimeFormat::initialize(ExecutionState& state, Object* dateTimeForma skeletonBuilder.appendString("MMMM"); } - doTable3(state.context()->staticStrings().lazyDay().string(), twoDightNumericValues, 2); + doTable4(state.context()->staticStrings().lazyDay().string(), twoDightNumericValues, 2); ret = opt.at("day"); if (ret->equals("2-digit")) { @@ -492,7 +529,10 @@ void IntlDateTimeFormat::initialize(ExecutionState& state, Object* dateTimeForma skeletonBuilder.appendString("d"); } - doTable3(state.context()->staticStrings().lazyHour().string(), twoDightNumericValues, 2); + doTable4(state.context()->staticStrings().lazyDayPeriod().string(), narrowShortLongValues, 3); + String* dayPeriodString = opt.at("dayPeriod"); + + doTable4(state.context()->staticStrings().lazyHour().string(), twoDightNumericValues, 2); String* hour = ret = opt.at("hour"); Value hr12Value = hour12; @@ -516,7 +556,17 @@ void IntlDateTimeFormat::initialize(ExecutionState& state, Object* dateTimeForma skeletonBuilder.appendChar('H'); } - doTable3(state.context()->staticStrings().lazyMinute().string(), twoDightNumericValues, 2); + // dayPeriod must be set after setting hour. + // https://unicode-org.atlassian.net/browse/ICU-20731 + if (dayPeriodString->equals("narrow")) { + skeletonBuilder.appendString("BBBBB"); + } else if (dayPeriodString->equals("short")) { + skeletonBuilder.appendString("B"); + } else if (dayPeriodString->equals("long")) { + skeletonBuilder.appendString("BBBB"); + } + + doTable4(state.context()->staticStrings().lazyMinute().string(), twoDightNumericValues, 2); ret = opt.at("minute"); if (ret->equals("2-digit")) { @@ -525,7 +575,7 @@ void IntlDateTimeFormat::initialize(ExecutionState& state, Object* dateTimeForma skeletonBuilder.appendString("m"); } - doTable3(state.context()->staticStrings().lazySecond().string(), twoDightNumericValues, 2); + doTable4(state.context()->staticStrings().lazySecond().string(), twoDightNumericValues, 2); ret = opt.at("second"); if (ret->equals("2-digit")) { @@ -534,8 +584,16 @@ void IntlDateTimeFormat::initialize(ExecutionState& state, Object* dateTimeForma skeletonBuilder.appendString("s"); } + Value fractionalSecondDigits = Intl::getNumberOption(state, options.asObject(), state.context()->staticStrings().lazyFractionalSecondDigits().string(), 1, 3, Value()); + if (!fractionalSecondDigits.isUndefined()) { + for (double i = 0; i < fractionalSecondDigits.asNumber(); i++) { + skeletonBuilder.appendString("S"); + } + opt.insert(std::make_pair("fractionalSecondDigits", fractionalSecondDigits.toString(state))); + } + Value shortLongValues[2] = { state.context()->staticStrings().lazyShort().string(), state.context()->staticStrings().lazyLong().string() }; - doTable3(state.context()->staticStrings().lazyTimeZoneName().string(), shortLongValues, 2); + doTable4(state.context()->staticStrings().lazyTimeZoneName().string(), shortLongValues, 2); ret = opt.at("timeZoneName"); if (ret->equals("short")) { @@ -544,24 +602,181 @@ void IntlDateTimeFormat::initialize(ExecutionState& state, Object* dateTimeForma skeletonBuilder.appendString("zzzz"); } - // Let dataLocaleData be the result of calling the [[Get]] internal method of localeData with argument dataLocale. - // Let formats be the result of calling the [[Get]] internal method of dataLocaleData with argument "formats". - // Let matcher be the result of calling the GetOption abstract operation with arguments options, - // "formatMatcher", "string", a List containing the two String values "basic" and "best fit", and "best fit". - Value formatMatcherValues[2] = { state.context()->staticStrings().lazyBasic().string(), state.context()->staticStrings().lazyBestFit().string() }; - matcher = Intl::getOption(state, options.asObject(), state.context()->staticStrings().lazyFormatMatcher().string(), Intl::StringValue, formatMatcherValues, 2, formatMatcherValues[1]); + // Let dataLocaleData be localeData.[[]]. + + matcherValues[0] = state.context()->staticStrings().lazyBasic().string(); + matcher = Intl::getOption(state, options.asObject(), state.context()->staticStrings().lazyFormatMatcher().string(), Intl::StringValue, matcherValues, 2, matcherValues[1]); + + // Let dateStyle be ? GetOption(options, "dateStyle", "string", « "full", "long", "medium", "short" », undefined). + // Set dateTimeFormat.[[DateStyle]] to dateStyle. + Value dateTimeStyleValues[4] = { state.context()->staticStrings().lazyFull().string(), state.context()->staticStrings().lazyLong().string(), + state.context()->staticStrings().lazyMedium().string(), state.context()->staticStrings().lazyShort().string() }; + Value dateStyle = Intl::getOption(state, options.asObject(), state.context()->staticStrings().lazyDateStyle().string(), Intl::StringValue, dateTimeStyleValues, 4, Value()); + m_dateStyle = dateStyle; + // Let timeStyle be ? GetOption(options, "timeStyle", "string", « "full", "long", "medium", "short" », undefined). + Value timeStyle = Intl::getOption(state, options.asObject(), state.context()->staticStrings().lazyTimeStyle().string(), Intl::StringValue, dateTimeStyleValues, 4, Value()); + // Set dateTimeFormat.[[TimeStyle]] to timeStyle. + m_timeStyle = timeStyle; + + UErrorCode status = U_ZERO_ERROR; + UTF16StringData skeleton; + UTF16StringDataNonGCStd patternBuffer; + + LocalResourcePointer generator(udatpg_open(dataLocale.toString(state)->toUTF8StringData().data(), &status), + [](UDateTimePatternGenerator* d) { udatpg_close(d); }); + if (U_FAILURE(status)) { + ErrorObject::throwBuiltinError(state, ErrorObject::TypeError, "failed to initialize DateTimeFormat"); + return; + } + + // If dateStyle is not undefined or timeStyle is not undefined, then + if (!dateStyle.isUndefined() || !timeStyle.isUndefined()) { + // For each row in Table 4, except the header row, do + // Let prop be the name given in the Property column of the row. + // Let p be opt.[[]]. + // If p is not undefined, then Throw a TypeError exception. + auto iter = opt.begin(); + while (iter != opt.end()) { + if (iter->second->length()) { + ErrorObject::throwBuiltinError(state, ErrorObject::TypeError, "dateStyle and timeStyle may not be used with other DateTimeFormat options"); + } + iter++; + } + // Let styles be dataLocaleData.[[styles]].[[]]. + // Let bestFormat be DateTimeStyleFormat(dateStyle, timeStyle, styles). + + auto convertFormatStyle = [](Value s) -> UDateFormatStyle { + if (s.isString()) { + String* style = s.asString(); + if (style->equals("full")) { + return UDAT_FULL; + } else if (style->equals("long")) { + return UDAT_LONG; + } else if (style->equals("medium")) { + return UDAT_MEDIUM; + } else if (style->equals("short")) { + return UDAT_SHORT; + } + } + return UDAT_NONE; + }; + + UErrorCode status = U_ZERO_ERROR; + LocalResourcePointer dateFormatFromStyle( + udat_open(convertFormatStyle(m_timeStyle), convertFormatStyle(m_dateStyle), dataLocaleWithExtensions.data(), m_timeZone->toUTF16StringData().data(), m_timeZone->length(), nullptr, -1, &status), + [](UDateFormat* fmt) { udat_close(fmt); }); + + if (U_FAILURE(status)) { + ErrorObject::throwBuiltinError(state, ErrorObject::TypeError, "failed to initialize DateTimeFormat"); + return; + } + + patternBuffer.resize(defaultStringBufferSize); + status = U_ZERO_ERROR; + auto patternLength = udat_toPattern(dateFormatFromStyle.get(), false, (UChar*)patternBuffer.data(), patternBuffer.size(), &status); + patternBuffer.resize(patternLength); + if (status == U_BUFFER_OVERFLOW_ERROR) { + status = U_ZERO_ERROR; + patternBuffer.resize(patternLength); + udat_toPattern(dateFormatFromStyle.get(), false, (UChar*)patternBuffer.data(), patternBuffer.size(), &status); + } + if (U_FAILURE(status)) { + ErrorObject::throwBuiltinError(state, ErrorObject::TypeError, "failed to initialize DateTimeFormat"); + return; + } + + // It is possible that timeStyle includes dayPeriod, which is sensitive to hour-cycle. + // If dayPeriod is included, just replacing hour based on hourCycle / hour12 produces strange results. + // Let's consider about the example. The formatted result looks like "02:12:47 PM Coordinated Universal Time" + // If we simply replace 02 to 14, this becomes "14:12:47 PM Coordinated Universal Time", this looks strange since "PM" is unnecessary! + // + // If the generated pattern's hour12 does not match against the option's one, we retrieve skeleton from the pattern, enforcing hour-cycle, + // and re-generating the best pattern from the modified skeleton. ICU will look into the generated skeleton, and pick the best format for the request. + // We do not care about h11 vs. h12 and h23 vs. h24 difference here since this will be later adjusted by replaceHourCycleInPattern. + // + // test262/test/intl402/DateTimeFormat/prototype/format/timedatestyle-en.js includes the test for this behavior. + if (!Value(m_timeStyle).isUndefined() && (!hourCycle.isUndefinedOrNull() || !hour12.isUndefined())) { + bool isHour12 = hourCycle.isString() && (hourCycle.asString()->equals("h11") || hourCycle.asString()->equals("h12")); + bool specifiedHour12 = false; + // If hour12 is specified, we prefer it and ignore hourCycle. + if (!hour12.isUndefined()) { + specifiedHour12 = hour12.asBoolean(); + } else { + specifiedHour12 = isHour12; + } + std::string extractedHourCycle = readHourCycleFromPattern(patternBuffer); + if (extractedHourCycle.size() && (extractedHourCycle == "h11" || extractedHourCycle == "h12") != specifiedHour12) { + UTF16StringDataNonGCStd skeleton; + skeleton.resize(defaultStringBufferSize); + status = U_ZERO_ERROR; + auto resultLength = udatpg_getSkeleton(nullptr, (UChar*)patternBuffer.data(), patternBuffer.size(), (UChar*)skeleton.data(), skeleton.size(), &status); + skeleton.resize(resultLength); + if (status == U_BUFFER_OVERFLOW_ERROR) { + status = U_ZERO_ERROR; + skeleton.resize(resultLength); + udatpg_getSkeleton(nullptr, (UChar*)patternBuffer.data(), patternBuffer.size(), (UChar*)skeleton.data(), skeleton.size(), &status); + } + if (U_FAILURE(status)) { + ErrorObject::throwBuiltinError(state, ErrorObject::TypeError, "failed to initialize DateTimeFormat"); + return; + } + + for (size_t i = 0; i < skeleton.size(); i++) { + auto ch = skeleton[i]; + if (ch == 'h' || ch == 'H' || ch == 'j') { + if (specifiedHour12) { + skeleton[i] = 'H'; + } else { + skeleton[i] = 'h'; + } + } + } - // Always use ICU date format generator, rather than our own pattern list and matcher. - // Covers steps 28-36. - String* skeleton = skeletonBuilder.finalize(); - UTF16StringData skeletonUTF16String = skeleton->toUTF16StringData(); + patternBuffer.resize(defaultStringBufferSize); + status = U_ZERO_ERROR; + auto patternLength = udatpg_getBestPatternWithOptions(generator.get(), (UChar*)skeleton.data(), skeleton.length(), UDATPG_MATCH_HOUR_FIELD_LENGTH, (UChar*)patternBuffer.data(), patternBuffer.size(), &status); + patternBuffer.resize(patternLength); + if (status == U_BUFFER_OVERFLOW_ERROR) { + status = U_ZERO_ERROR; + patternBuffer.resize(patternLength); + udatpg_getBestPatternWithOptions(generator.get(), (UChar*)skeleton.data(), skeleton.length(), UDATPG_MATCH_HOUR_FIELD_LENGTH, (UChar*)patternBuffer.data(), patternBuffer.size(), &status); + } + if (U_FAILURE(status)) { + ErrorObject::throwBuiltinError(state, ErrorObject::TypeError, "failed to initialize DateTimeFormat"); + return; + } + } + } + + } else { + // Else, + // Let formats be dataLocaleData.[[formats]].[[]]. + // If matcher is "basic", then + // Let bestFormat be BasicFormatMatcher(opt, formats). + // Else, + // Let bestFormat be BestFitFormatMatcher(opt, formats). + skeleton = skeletonBuilder.finalize()->toUTF16StringData(); + patternBuffer.resize(defaultStringBufferSize); + status = U_ZERO_ERROR; + auto patternLength = udatpg_getBestPatternWithOptions(generator.get(), (UChar*)skeleton.data(), skeleton.length(), UDATPG_MATCH_HOUR_FIELD_LENGTH, (UChar*)patternBuffer.data(), patternBuffer.size(), &status); + patternBuffer.resize(patternLength); + if (status == U_BUFFER_OVERFLOW_ERROR) { + status = U_ZERO_ERROR; + patternBuffer.resize(patternLength); + udatpg_getBestPatternWithOptions(generator.get(), (UChar*)skeleton.data(), skeleton.length(), UDATPG_MATCH_HOUR_FIELD_LENGTH, (UChar*)patternBuffer.data(), patternBuffer.size(), &status); + } + if (U_FAILURE(status)) { + ErrorObject::throwBuiltinError(state, ErrorObject::TypeError, "failed to initialize DateTimeFormat"); + return; + } + } // If dateTimeFormat.[[Hour]] is not undefined, then bool hasHourOption = hour->length(); if (hasHourOption) { // Let hcDefault be dataLocaleData.[[hourCycle]]. UTF16StringDataNonGCStd patternBuffer; - patternBuffer.resize(32); + patternBuffer.resize(defaultStringBufferSize); status = U_ZERO_ERROR; auto patternLength = udatpg_getBestPattern(generator.get(), u"jjmm", 4, (UChar*)patternBuffer.data(), patternBuffer.length(), &status); patternBuffer.resize(patternLength); @@ -573,9 +788,9 @@ void IntlDateTimeFormat::initialize(ExecutionState& state, Object* dateTimeForma ASSERT(U_SUCCESS(status)); auto hcDefault = readHourCycleFromPattern(patternBuffer); // Let hc be dateTimeFormat.[[HourCycle]]. - auto hc = dateTimeFormat->internalSlot()->get(state, ObjectPropertyName(state.context()->staticStrings().hourCycle)).value(state, dateTimeFormat->internalSlot()).asString(); + auto hc = m_hourCycle; // If hc is null, then - if (!hc->length()) { + if (Value(hc).isUndefined()) { // Set hc to hcDefault. hc = String::fromUTF8(hcDefault.data(), hcDefault.size()); } @@ -606,33 +821,34 @@ void IntlDateTimeFormat::initialize(ExecutionState& state, Object* dateTimeForma } // Let dateTimeFormat.[[HourCycle]] to hc. - dateTimeFormat->internalSlot()->set(state, ObjectPropertyName(state.context()->staticStrings().hourCycle), Value(hc), dateTimeFormat->internalSlot()); + // If dateTimeformat.[[HourCycle]] is "h11" or "h12", then + // Let pattern be bestFormat.[[pattern12]]. + // Let rangePatterns be bestFormat.[[rangePatterns12]]. + // Else, + // Let pattern be bestFormat.[[pattern]]. + // Let rangePatterns be bestFormat.[[rangePatterns]]. + m_hourCycle = hc; } else { // Set dateTimeFormat.[[HourCycle]] to undefined. - dateTimeFormat->internalSlot()->set(state, ObjectPropertyName(state.context()->staticStrings().hourCycle), Value(), dateTimeFormat->internalSlot()); // Let pattern be bestFormat.[[pattern]]. + // Let rangePatterns be bestFormat.[[rangePatterns]]. + m_hourCycle = Value(); } - UTF16StringDataNonGCStd patternBuffer; - patternBuffer.resize(32); - status = U_ZERO_ERROR; - auto patternLength = udatpg_getBestPatternWithOptions(generator.get(), (UChar*)skeletonUTF16String.data(), skeletonUTF16String.length(), UDATPG_MATCH_HOUR_FIELD_LENGTH, (UChar*)patternBuffer.data(), patternBuffer.size(), &status); - patternBuffer.resize(patternLength); - if (status == U_BUFFER_OVERFLOW_ERROR) { - status = U_ZERO_ERROR; - patternBuffer.resize(patternLength); - udatpg_getBestPatternWithOptions(generator.get(), (UChar*)skeletonUTF16String.data(), skeletonUTF16String.length(), UDATPG_MATCH_HOUR_FIELD_LENGTH, (UChar*)patternBuffer.data(), patternLength, &status); - } - if (U_FAILURE(status)) { - ErrorObject::throwBuiltinError(state, ErrorObject::TypeError, "failed to initialize DateTimeFormat"); - return; - } + // Set dateTimeFormat.[[Pattern]] to pattern. + // Set dateTimeFormat.[[RangePatterns]] to rangePatterns. + // Return dateTimeFormat. - Value hc = dateTimeFormat->internalSlot()->get(state, ObjectPropertyName(state.context()->staticStrings().hourCycle)).value(state, dateTimeFormat->internalSlot()); - if (!hc.isUndefined() && hc.asString()->length()) { - patternBuffer = updateHourCycleInPatternDueToHourCycle(patternBuffer, hc.asString()); + // After generating pattern from skeleton, we need to change h11 vs. h12 and h23 vs. h24 if hourCycle is specified. + if (!Value(m_hourCycle).isUndefined()) { + patternBuffer = updateHourCycleInPatternDueToHourCycle(patternBuffer, Value(m_hourCycle).asString()); } + // For each row in Table 4, except the header row, in table order, do + // Let prop be the name given in the Property column of the row. + // If bestFormat has a field [[]], then + // Let p be bestFormat.[[]]. + // Set dateTimeFormat's internal slot whose name is the Internal Slot column of the row to p. bool inQuote = false; unsigned length = patternBuffer.length(); for (unsigned i = 0; i < length; ++i) { @@ -653,120 +869,134 @@ void IntlDateTimeFormat::initialize(ExecutionState& state, Object* dateTimeForma if (hasHourOption && !inQuote) { if (currentCharacter == 'h' || currentCharacter == 'K') { - dateTimeFormat->internalSlot()->set(state, ObjectPropertyName(state.context()->staticStrings().lazyHour12()), Value(true), dateTimeFormat->internalSlot()); + m_hour12 = Value(true); } else if (currentCharacter == 'H' || currentCharacter == 'k') { - dateTimeFormat->internalSlot()->set(state, ObjectPropertyName(state.context()->staticStrings().lazyHour12()), Value(false), dateTimeFormat->internalSlot()); + m_hour12 = Value(false); } } switch (currentCharacter) { case 'G': - if (count <= 3) - dateTimeFormat->internalSlot()->set(state, ObjectPropertyName(state.context()->staticStrings().lazyEra()), Value(state.context()->staticStrings().lazyShort().string()), dateTimeFormat->internalSlot()); - else if (count == 4) - dateTimeFormat->internalSlot()->set(state, ObjectPropertyName(state.context()->staticStrings().lazyEra()), Value(state.context()->staticStrings().lazyLong().string()), dateTimeFormat->internalSlot()); - else if (count == 5) - dateTimeFormat->internalSlot()->set(state, ObjectPropertyName(state.context()->staticStrings().lazyEra()), Value(state.context()->staticStrings().lazyNarrow().string()), dateTimeFormat->internalSlot()); + if (count <= 3) { + m_era = state.context()->staticStrings().lazyShort().string(); + } else if (count == 4) { + m_era = state.context()->staticStrings().lazyLong().string(); + } else if (count == 5) { + m_era = state.context()->staticStrings().lazyNarrow().string(); + } break; case 'y': - if (count == 1) - dateTimeFormat->internalSlot()->set(state, ObjectPropertyName(state.context()->staticStrings().lazyYear()), Value(state.context()->staticStrings().numeric.string()), dateTimeFormat->internalSlot()); - else if (count == 2) - dateTimeFormat->internalSlot()->set(state, ObjectPropertyName(state.context()->staticStrings().lazyYear()), Value(state.context()->staticStrings().lazyTwoDigit().string()), dateTimeFormat->internalSlot()); + if (count == 1) { + m_year = state.context()->staticStrings().numeric.string(); + } else if (count == 2) { + m_year = state.context()->staticStrings().lazyTwoDigit().string(); + } break; case 'M': case 'L': - if (count == 1) - dateTimeFormat->internalSlot()->set(state, ObjectPropertyName(state.context()->staticStrings().lazyMonth()), Value(state.context()->staticStrings().numeric.string()), dateTimeFormat->internalSlot()); - else if (count == 2) - dateTimeFormat->internalSlot()->set(state, ObjectPropertyName(state.context()->staticStrings().lazyMonth()), Value(state.context()->staticStrings().lazyTwoDigit().string()), dateTimeFormat->internalSlot()); - else if (count == 3) - dateTimeFormat->internalSlot()->set(state, ObjectPropertyName(state.context()->staticStrings().lazyMonth()), Value(state.context()->staticStrings().lazyShort().string()), dateTimeFormat->internalSlot()); - else if (count == 4) - dateTimeFormat->internalSlot()->set(state, ObjectPropertyName(state.context()->staticStrings().lazyMonth()), Value(state.context()->staticStrings().lazyLong().string()), dateTimeFormat->internalSlot()); - else if (count == 5) - dateTimeFormat->internalSlot()->set(state, ObjectPropertyName(state.context()->staticStrings().lazyMonth()), Value(state.context()->staticStrings().lazyNarrow().string()), dateTimeFormat->internalSlot()); + if (count == 1) { + m_month = state.context()->staticStrings().numeric.string(); + } else if (count == 2) { + m_month = state.context()->staticStrings().lazyTwoDigit().string(); + } else if (count == 3) { + m_month = state.context()->staticStrings().lazyShort().string(); + } else if (count == 4) { + m_month = state.context()->staticStrings().lazyLong().string(); + } else if (count == 5) { + m_month = state.context()->staticStrings().lazyNarrow().string(); + } break; case 'E': case 'e': case 'c': - if (count <= 3) - dateTimeFormat->internalSlot()->set(state, ObjectPropertyName(state.context()->staticStrings().lazyWeekday()), Value(state.context()->staticStrings().lazyShort().string()), dateTimeFormat->internalSlot()); - else if (count == 4) - dateTimeFormat->internalSlot()->set(state, ObjectPropertyName(state.context()->staticStrings().lazyWeekday()), Value(state.context()->staticStrings().lazyLong().string()), dateTimeFormat->internalSlot()); - else if (count == 5) - dateTimeFormat->internalSlot()->set(state, ObjectPropertyName(state.context()->staticStrings().lazyWeekday()), Value(state.context()->staticStrings().lazyNarrow().string()), dateTimeFormat->internalSlot()); + if (count <= 3) { + m_weekday = state.context()->staticStrings().lazyShort().string(); + } else if (count == 4) { + m_weekday = state.context()->staticStrings().lazyLong().string(); + } else if (count == 5) { + m_weekday = state.context()->staticStrings().lazyNarrow().string(); + } break; case 'd': - if (count == 1) - dateTimeFormat->internalSlot()->set(state, ObjectPropertyName(state.context()->staticStrings().lazyDay()), Value(state.context()->staticStrings().numeric.string()), dateTimeFormat->internalSlot()); - else if (count == 2) - dateTimeFormat->internalSlot()->set(state, ObjectPropertyName(state.context()->staticStrings().lazyDay()), Value(state.context()->staticStrings().lazyTwoDigit().string()), dateTimeFormat->internalSlot()); + if (count == 1) { + m_day = state.context()->staticStrings().numeric.string(); + } else if (count == 2) { + m_day = state.context()->staticStrings().lazyTwoDigit().string(); + } + break; + case 'a': + case 'b': + case 'B': + if (count <= 3) { + m_dayPeriod = state.context()->staticStrings().lazyShort().string(); + } else if (count == 4) { + m_dayPeriod = state.context()->staticStrings().lazyLong().string(); + } else if (count == 5) { + m_dayPeriod = state.context()->staticStrings().lazyNarrow().string(); + } break; case 'h': case 'H': case 'k': case 'K': - if (count == 1) - dateTimeFormat->internalSlot()->set(state, ObjectPropertyName(state.context()->staticStrings().lazyHour()), Value(state.context()->staticStrings().numeric.string()), dateTimeFormat->internalSlot()); - else if (count == 2) - dateTimeFormat->internalSlot()->set(state, ObjectPropertyName(state.context()->staticStrings().lazyHour()), Value(state.context()->staticStrings().lazyTwoDigit().string()), dateTimeFormat->internalSlot()); + if (count == 1) { + m_hour = state.context()->staticStrings().numeric.string(); + } else if (count == 2) { + m_hour = state.context()->staticStrings().lazyTwoDigit().string(); + } break; case 'm': - if (count == 1) - dateTimeFormat->internalSlot()->set(state, ObjectPropertyName(state.context()->staticStrings().lazyMinute()), Value(state.context()->staticStrings().numeric.string()), dateTimeFormat->internalSlot()); - else if (count == 2) - dateTimeFormat->internalSlot()->set(state, ObjectPropertyName(state.context()->staticStrings().lazyMinute()), Value(state.context()->staticStrings().lazyTwoDigit().string()), dateTimeFormat->internalSlot()); + if (count == 1) { + m_minute = state.context()->staticStrings().numeric.string(); + } else if (count == 2) { + m_minute = state.context()->staticStrings().lazyTwoDigit().string(); + } break; case 's': - if (count == 1) - dateTimeFormat->internalSlot()->set(state, ObjectPropertyName(state.context()->staticStrings().lazySecond()), Value(state.context()->staticStrings().numeric.string()), dateTimeFormat->internalSlot()); - else if (count == 2) - dateTimeFormat->internalSlot()->set(state, ObjectPropertyName(state.context()->staticStrings().lazySecond()), Value(state.context()->staticStrings().lazyTwoDigit().string()), dateTimeFormat->internalSlot()); + if (count == 1) { + m_second = state.context()->staticStrings().numeric.string(); + } else if (count == 2) { + m_second = state.context()->staticStrings().lazyTwoDigit().string(); + } break; case 'z': case 'v': case 'V': - if (count == 1) - dateTimeFormat->internalSlot()->set(state, ObjectPropertyName(state.context()->staticStrings().lazyTimeZoneName()), Value(state.context()->staticStrings().lazyShort().string()), dateTimeFormat->internalSlot()); - else if (count == 4) - dateTimeFormat->internalSlot()->set(state, ObjectPropertyName(state.context()->staticStrings().lazyTimeZoneName()), Value(state.context()->staticStrings().lazyLong().string()), dateTimeFormat->internalSlot()); + if (count == 1) { + m_timeZoneName = state.context()->staticStrings().lazyShort().string(); + } else if (count == 4) { + m_timeZoneName = state.context()->staticStrings().lazyLong().string(); + } + break; + case 'S': + m_fractionalSecondDigits = Value(count); break; } } status = U_ZERO_ERROR; - UTF16StringData timeZoneView = dateTimeFormat->internalSlot()->get(state, ObjectPropertyName(state.context()->staticStrings().lazyTimeZone())).value(state, dateTimeFormat->internalSlot()).toString(state)->toUTF16StringData(); - UTF8StringData localeStringView = r.at("locale")->toUTF8StringData(); - UDateFormat* icuDateFormat = udat_open(UDAT_PATTERN, UDAT_PATTERN, localeStringView.data(), (UChar*)timeZoneView.data(), timeZoneView.length(), (UChar*)patternBuffer.data(), patternBuffer.length(), &status); + UTF16StringData timeZoneView = m_timeZone->toUTF16StringData(); + m_icuDateFormat = udat_open(UDAT_PATTERN, UDAT_PATTERN, dataLocaleWithExtensions.data(), (UChar*)timeZoneView.data(), timeZoneView.length(), (UChar*)patternBuffer.data(), patternBuffer.length(), &status); if (U_FAILURE(status)) { ErrorObject::throwBuiltinError(state, ErrorObject::TypeError, "failed to initialize DateTimeFormat"); return; } - dateTimeFormat->internalSlot()->setExtraData(icuDateFormat); - - dateTimeFormat->internalSlot()->addFinalizer([](Object* obj, void* data) { - Object* self = (Object*)obj; - udat_close((UDateFormat*)self->extraData()); + addFinalizer([](Object* obj, void* data) { + IntlDateTimeFormatObject* self = (IntlDateTimeFormatObject*)obj; + udat_close(self->m_icuDateFormat); }, - nullptr); - - // Set dateTimeFormat.[[boundFormat]] to undefined. - // Set dateTimeFormat.[[initializedDateTimeFormat]] to true. - dateTimeFormat->internalSlot()->defineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().lazyInitializedDateTimeFormat()), ObjectPropertyDescriptor(Value(true))); + nullptr); status = U_ZERO_ERROR; - UCalendar* cal = const_cast(udat_getCalendar(icuDateFormat)); + UCalendar* cal = const_cast(udat_getCalendar(m_icuDateFormat)); std::string type(ucal_getType(cal, &status)); if (status == U_ZERO_ERROR && std::string("gregorian") == type) { ucal_setGregorianChange(cal, minECMAScriptTime, &status); } - // Return dateTimeFormat. - return; } -UTF16StringDataNonGCStd IntlDateTimeFormat::format(ExecutionState& state, Object* dateTimeFormat, double x) +UTF16StringDataNonGCStd IntlDateTimeFormatObject::format(ExecutionState& state, double x) { // If x is not a finite Number, then throw a RangeError exception. // If x is NaN, throw a RangeError exception @@ -777,12 +1007,12 @@ UTF16StringDataNonGCStd IntlDateTimeFormat::format(ExecutionState& state, Object x = Value(x).toInteger(state); - UDateFormat* udat = (UDateFormat*)dateTimeFormat->internalSlot()->extraData(); + UDateFormat* udat = (UDateFormat*)m_icuDateFormat; // Delegate remaining steps to ICU. UErrorCode status = U_ZERO_ERROR; UTF16StringDataNonGCStd result; - result.resize(32); + result.resize(defaultStringBufferSize); auto resultLength = udat_format(udat, x, (UChar*)result.data(), result.size(), nullptr, &status); result.resize(resultLength); @@ -797,53 +1027,7 @@ UTF16StringDataNonGCStd IntlDateTimeFormat::format(ExecutionState& state, Object return result; } - -static String* icuFieldTypeToPartName(ExecutionState& state, int32_t fieldName) -{ - if (fieldName == -1) { - return state.context()->staticStrings().lazyLiteral().string(); - } - - switch ((UDateFormatField)fieldName) { - case UDAT_ERA_FIELD: - return state.context()->staticStrings().lazyEra().string(); - case UDAT_YEAR_FIELD: - case UDAT_YEAR_WOY_FIELD: - case UDAT_EXTENDED_YEAR_FIELD: - case UDAT_YEAR_NAME_FIELD: - return state.context()->staticStrings().lazyYear().string(); - case UDAT_MONTH_FIELD: - case UDAT_STANDALONE_MONTH_FIELD: - return state.context()->staticStrings().lazyMonth().string(); - case UDAT_DATE_FIELD: - case UDAT_JULIAN_DAY_FIELD: - return state.context()->staticStrings().lazyDay().string(); - case UDAT_HOUR_OF_DAY1_FIELD: - case UDAT_HOUR_OF_DAY0_FIELD: - case UDAT_HOUR1_FIELD: - case UDAT_HOUR0_FIELD: - return state.context()->staticStrings().lazyHour().string(); - case UDAT_MINUTE_FIELD: - return state.context()->staticStrings().lazyMinute().string(); - case UDAT_SECOND_FIELD: - return state.context()->staticStrings().lazySecond().string(); - case UDAT_DAY_OF_WEEK_FIELD: - case UDAT_STANDALONE_DAY_FIELD: - case UDAT_DOW_LOCAL_FIELD: - case UDAT_DAY_OF_WEEK_IN_MONTH_FIELD: - return state.context()->staticStrings().lazyWeekday().string(); - case UDAT_AM_PM_FIELD: - return state.context()->staticStrings().lazyDayPeriod().string(); - case UDAT_TIMEZONE_FIELD: - return state.context()->staticStrings().lazyTimeZoneName().string(); - default: - ASSERT_NOT_REACHED(); - return String::emptyString; - } -} - - -ArrayObject* IntlDateTimeFormat::formatToParts(ExecutionState& state, Object* dateTimeFormat, double x) +ArrayObject* IntlDateTimeFormatObject::formatToParts(ExecutionState& state, double x) { // If x is not a finite Number, then throw a RangeError exception. // If x is NaN, throw a RangeError exception @@ -856,7 +1040,7 @@ ArrayObject* IntlDateTimeFormat::formatToParts(ExecutionState& state, Object* da ArrayObject* result = new ArrayObject(state); - UDateFormat* udat = (UDateFormat*)dateTimeFormat->internalSlot()->extraData(); + UDateFormat* udat = (UDateFormat*)m_icuDateFormat; UErrorCode status = U_ZERO_ERROR; @@ -865,7 +1049,7 @@ ArrayObject* IntlDateTimeFormat::formatToParts(ExecutionState& state, Object* da ASSERT(U_SUCCESS(status)); UTF16StringDataNonGCStd resultString; - resultString.resize(32); + resultString.resize(defaultStringBufferSize); auto resultLength = udat_formatForFields(udat, x, (UChar*)resultString.data(), resultString.size(), fpositer, &status); resultString.resize(resultLength); @@ -961,7 +1145,7 @@ ArrayObject* IntlDateTimeFormat::formatToParts(ExecutionState& state, Object* da return result; } -Value IntlDateTimeFormat::toDateTimeOptions(ExecutionState& state, Value options, Value required, Value defaults) +Value IntlDateTimeFormatObject::toDateTimeOptions(ExecutionState& state, Value options, Value required, Value defaults) { // If options is undefined, then let options be null, else let options be ToObject(options). if (options.isUndefined()) { @@ -969,10 +1153,14 @@ Value IntlDateTimeFormat::toDateTimeOptions(ExecutionState& state, Value options } else { options = options.toObject(state); } - // Let create be the standard built-in function object defined in ES5, 15.2.3.5. - // Let options be the result of calling the [[Call]] internal method of create with undefined as the this value - // and an argument list containing the single item options. - options = Object::call(state, state.context()->globalObject()->objectCreate(), Value(), 1, &options); + // Let options be OrdinaryObjectCreate(options). + if (options.isObject()) { + Value proto = options; + options = new Object(state); + options.asObject()->setPrototype(state, proto); + } else { + options = new Object(state, Object::PrototypeIsNull); + } // Let needDefaults be true. bool needDefaults = true; @@ -987,11 +1175,36 @@ Value IntlDateTimeFormat::toDateTimeOptions(ExecutionState& state, Value options } // If required is "time" or "any", then if (required.equalsTo(state, state.context()->staticStrings().lazyTime().string()) || required.equalsTo(state, state.context()->staticStrings().lazyAny().string())) { - // For each of the property names "hour", "minute", "second": + // For each of the property names "dayPeriod", "hour", "minute", "second", "fractionalSecondDigits" // If the result of calling the [[Get]] internal method of options with the property name is not undefined, then let needDefaults be false. + toDateTimeOptionsTest(state, options, state.context()->staticStrings().lazyDayPeriod(), needDefaults); toDateTimeOptionsTest(state, options, state.context()->staticStrings().lazyHour(), needDefaults); toDateTimeOptionsTest(state, options, state.context()->staticStrings().lazyMinute(), needDefaults); toDateTimeOptionsTest(state, options, state.context()->staticStrings().lazySecond(), needDefaults); + toDateTimeOptionsTest(state, options, state.context()->staticStrings().lazyFractionalSecondDigits(), needDefaults); + } + + // Let dateStyle be ? Get(options, "dateStyle"). + Value dateStyle = options.asObject()->get(state, state.context()->staticStrings().lazyDateStyle()).value(state, options); + // Let timeStyle be ? Get(options, "timeStyle"). + Value timeStyle = options.asObject()->get(state, state.context()->staticStrings().lazyTimeStyle()).value(state, options); + // If dateStyle is not undefined or timeStyle is not undefined, let needDefaults be false. + if (!dateStyle.isUndefined() || !timeStyle.isUndefined()) { + needDefaults = false; + } + // If required is "date" and timeStyle is not undefined, then + if (required.equalsTo(state, state.context()->staticStrings().lazyDate().string())) { + if (!timeStyle.isUndefined()) { + // Throw a TypeError exception. + ErrorObject::throwBuiltinError(state, ErrorObject::TypeError, "The given option value is invalid"); + } + } + // If required is "time" and dateStyle is not undefined, then + if (required.equalsTo(state, state.context()->staticStrings().lazyTime().string())) { + if (!dateStyle.isUndefined()) { + // Throw a TypeError exception. + ErrorObject::throwBuiltinError(state, ErrorObject::TypeError, "The given option value is invalid"); + } } // If needDefaults is true and defaults is either "date" or "all", then diff --git a/lwnode/code/escargotshim/deps/escargot/src/intl/IntlDateTimeFormat.h b/lwnode/code/escargotshim/deps/escargot/src/intl/IntlDateTimeFormat.h index 49eda7a..940a2f4 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/intl/IntlDateTimeFormat.h +++ b/lwnode/code/escargotshim/deps/escargot/src/intl/IntlDateTimeFormat.h @@ -26,13 +26,138 @@ namespace Escargot { -class IntlDateTimeFormat { +class IntlDateTimeFormatObject : public Object { public: - static Object* create(ExecutionState& state, Context* realm, Value locales, Value options); - static void initialize(ExecutionState& state, Object* dateTimeFormat, Value locales, Value options); - static UTF16StringDataNonGCStd format(ExecutionState& state, Object* dateTimeFormat, double x); - static ArrayObject* formatToParts(ExecutionState& state, Object* dateTimeFormat, double x); + IntlDateTimeFormatObject(ExecutionState& state, Value locales, Value options); + IntlDateTimeFormatObject(ExecutionState& state, Object* proto, Value locales, Value options); + + virtual bool isIntlDateTimeFormatObject() const override + { + return true; + } + + UTF16StringDataNonGCStd format(ExecutionState& state, double x); + ArrayObject* formatToParts(ExecutionState& state, double x); static Value toDateTimeOptions(ExecutionState& state, Value options, Value required, Value defaults); + + String* locale() const + { + return m_locale; + } + + String* calendar() const + { + return m_calendar; + } + + String* numberingSystem() const + { + return m_numberingSystem; + } + + String* timeZone() const + { + return m_timeZone; + } + + Value hour12() const + { + return m_hour12; + } + + Value era() const + { + return m_era; + } + + Value year() const + { + return m_year; + } + + Value month() const + { + return m_month; + } + + Value weekday() const + { + return m_weekday; + } + + Value day() const + { + return m_day; + } + + Value dayPeriod() const + { + return m_dayPeriod; + } + + Value hour() const + { + return m_hour; + } + + Value hourCycle() const + { + return m_hourCycle; + } + + Value minute() const + { + return m_minute; + } + + Value second() const + { + return m_second; + } + + Value timeZoneName() const + { + return m_timeZoneName; + } + + Value fractionalSecondDigits() const + { + return m_fractionalSecondDigits; + } + + Value dateStyle() const + { + return m_dateStyle; + } + + Value timeStyle() const + { + return m_timeStyle; + } + +protected: + String* m_locale; + String* m_calendar; + String* m_numberingSystem; + String* m_timeZone; + + EncodedValue m_hour12; + EncodedValue m_era; + EncodedValue m_year; + EncodedValue m_month; + EncodedValue m_weekday; + EncodedValue m_day; + EncodedValue m_dayPeriod; + EncodedValue m_hour; + EncodedValue m_hourCycle; + EncodedValue m_minute; + EncodedValue m_second; + EncodedValue m_timeZoneName; + EncodedValue m_fractionalSecondDigits; + EncodedValue m_dateStyle; + EncodedValue m_timeStyle; + + UDateFormat* m_icuDateFormat; }; } // namespace Escargot diff --git a/lwnode/code/escargotshim/deps/escargot/src/intl/IntlNumberFormat.cpp b/lwnode/code/escargotshim/deps/escargot/src/intl/IntlNumberFormat.cpp index 21454f7..d05d7ca 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/intl/IntlNumberFormat.cpp +++ b/lwnode/code/escargotshim/deps/escargot/src/intl/IntlNumberFormat.cpp @@ -142,29 +142,6 @@ static Value defaultNumberOption(ExecutionState& state, Value value, double mini } } -static double getNumberOption(ExecutionState& state, Object* options, String* property, double minimum, double maximum, double fallback) -{ - // http://www.ecma-international.org/ecma-402/1.0/index.html#sec-9.2.10 - - // Let value be the result of calling the [[Get]] internal method of options with argument property. - Value value = options->get(state, ObjectPropertyName(state, property)).value(state, options); - // If value is not undefined, then - if (!value.isUndefined()) { - // Let value be ToNumber(value). - double doubleValue = value.toNumber(state); - // If value is NaN or less than minimum or greater than maximum, throw a RangeError exception. - if (std::isnan(doubleValue) || doubleValue < minimum || maximum < doubleValue) { - ErrorObject::throwBuiltinError(state, ErrorObject::RangeError, "Got invalid number option value"); - } - // Return floor(value). - return floor(doubleValue); - } else { - // Else return fallback. - return fallback; - } -} - - Object* IntlNumberFormat::create(ExecutionState& state, Context* realm, Value locales, Value options) { Object* numberFormat = new Object(state, realm->globalObject()->intlNumberFormatPrototype()); @@ -525,7 +502,7 @@ void IntlNumberFormat::initialize(ExecutionState& state, Object* numberFormat, V // Perform ? SetNumberFormatDigitOptions(numberFormat, options, mnfdDefault, mxfdDefault, notation). // Let mnid be ? GetNumberOption(options, "minimumIntegerDigits,", 1, 21, 1). - double mnid = getNumberOption(state, options.asObject(), state.context()->staticStrings().lazyMinimumIntegerDigits().string(), 1, 21, 1); + double mnid = Intl::getNumberOption(state, options.asObject(), state.context()->staticStrings().lazyMinimumIntegerDigits().string(), 1, 21, 1); // Let mnfd be ? Get(options, "minimumFractionDigits"). Value mnfd; auto g = options.asObject()->get(state, ObjectPropertyName(state.context()->staticStrings().lazyMinimumFractionDigits())); diff --git a/lwnode/code/escargotshim/deps/escargot/src/parser/CodeBlock.h b/lwnode/code/escargotshim/deps/escargot/src/parser/CodeBlock.h index 9ab701f..ca5d782 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/parser/CodeBlock.h +++ b/lwnode/code/escargotshim/deps/escargot/src/parser/CodeBlock.h @@ -173,16 +173,25 @@ struct InterpretedCodeBlockRareData : public gc { FunctionContextVarMap* m_identifierInfoMap; TightVector, GCUtil::gc_malloc_allocator>> m_taggedTemplateLiteralCache; AtomicStringTightVector* m_classPrivateNames; +#ifdef ESCARGOT_DEBUGGER + size_t m_debuggerLineStart; +#endif /* ESCARGOT_DEBUGGER */ InterpretedCodeBlockRareData() : m_identifierInfoMap(nullptr) , m_classPrivateNames(nullptr) +#ifdef ESCARGOT_DEBUGGER + , m_debuggerLineStart(SIZE_MAX) +#endif /* ESCARGOT_DEBUGGER */ { } InterpretedCodeBlockRareData(FunctionContextVarMap* map, AtomicStringTightVector* classPrivateNames) : m_identifierInfoMap(map) , m_classPrivateNames(classPrivateNames) +#ifdef ESCARGOT_DEBUGGER + , m_debuggerLineStart(SIZE_MAX) +#endif /* ESCARGOT_DEBUGGER */ { } }; @@ -966,6 +975,9 @@ private: , m_rareData(new InterpretedCodeBlockRareData(scopeCtx->m_varNamesMap, scopeCtx->m_classPrivateNames)) { ASSERT(scopeCtx->m_needRareData); +#ifdef ESCARGOT_DEBUGGER + m_rareData->m_debuggerLineStart = scopeCtx->m_debuggerLineStart; +#endif /* ESCARGOT_DEBUGGER */ } InterpretedCodeBlockWithRareData(Context* ctx, Script* script, StringView src, ASTScopeContext* scopeCtx, InterpretedCodeBlock* parentBlock, bool isEvalCode, bool isEvalCodeInFunction) @@ -973,6 +985,9 @@ private: , m_rareData(new InterpretedCodeBlockRareData(scopeCtx->m_varNamesMap, scopeCtx->m_classPrivateNames)) { ASSERT(scopeCtx->m_needRareData); +#ifdef ESCARGOT_DEBUGGER + m_rareData->m_debuggerLineStart = scopeCtx->m_debuggerLineStart; +#endif /* ESCARGOT_DEBUGGER */ } InterpretedCodeBlockWithRareData(Context* ctx, Script* script) diff --git a/lwnode/code/escargotshim/deps/escargot/src/parser/ast/ASTContext.h b/lwnode/code/escargotshim/deps/escargot/src/parser/ast/ASTContext.h index 24fa9de..3cffead 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/parser/ast/ASTContext.h +++ b/lwnode/code/escargotshim/deps/escargot/src/parser/ast/ASTContext.h @@ -323,6 +323,11 @@ struct ASTScopeContext { NodeLOC m_bodyEndLOC; #endif +#ifdef ESCARGOT_DEBUGGER + // This field is storing line info data for class field initializers + size_t m_debuggerLineStart; +#endif /* ESCARGOT_DEBUGGER */ + // ASTScopeContext is allocated by ASTAllocator inline void *operator new(size_t size, ASTAllocator &allocator) { @@ -695,6 +700,9 @@ struct ASTScopeContext { #else , m_bodyEndLOC(SIZE_MAX) #endif +#ifdef ESCARGOT_DEBUGGER + , m_debuggerLineStart(SIZE_MAX) +#endif /* ESCARGOT_DEBUGGER */ { } }; diff --git a/lwnode/code/escargotshim/deps/escargot/src/parser/ast/ForInOfStatementNode.h b/lwnode/code/escargotshim/deps/escargot/src/parser/ast/ForInOfStatementNode.h index 219bde4..694c6a9 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/parser/ast/ForInOfStatementNode.h +++ b/lwnode/code/escargotshim/deps/escargot/src/parser/ast/ForInOfStatementNode.h @@ -402,7 +402,7 @@ public: size_t returnUndefinedTestRegister = newContext.getRegister(); codeBlock->pushCode(LoadLiteral(ByteCodeLOC(m_loc.index), returnUndefinedTestRegister, Value()), &newContext, this); size_t returnUndefinedCompareJump = codeBlock->currentCodeSize(); - codeBlock->pushCode(JumpIfEqual(ByteCodeLOC(m_loc.index), returnUndefinedTestRegister, returnOrInnerResultRegister, false, true), &newContext, this); + codeBlock->pushCode(JumpIfEqual(ByteCodeLOC(m_loc.index), returnUndefinedTestRegister, returnOrInnerResultRegister, false, false), &newContext, this); newContext.giveUpRegister(); // drop returnUndefinedTestRegister // Let innerResult be Call(return, iterator, « »). diff --git a/lwnode/code/escargotshim/deps/escargot/src/parser/ast/ReturnStatementNode.h b/lwnode/code/escargotshim/deps/escargot/src/parser/ast/ReturnStatementNode.h index 7a9d49e..a42b5ed 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/parser/ast/ReturnStatementNode.h +++ b/lwnode/code/escargotshim/deps/escargot/src/parser/ast/ReturnStatementNode.h @@ -39,9 +39,17 @@ public: if (context->m_breakpointContext->m_breakpointLocations.size() == 0) { ASSERT(context->m_breakpointContext->m_lastBreakpointLineOffset == 0); ASSERT(context->m_breakpointContext->m_breakpointLocations.size() == 0); - ExtendedNodeLOC sourceElementStart = context->m_codeBlock->functionStart(); - size_t lastLineOffset = context->calculateBreakpointLineOffset(m_loc.index, sourceElementStart); - context->insertBreakpointAt(lastLineOffset + sourceElementStart.line, this); + + InterpretedCodeBlock* interpretedCodeBlock = context->m_codeBlock; + + if (interpretedCodeBlock->hasRareData() && interpretedCodeBlock->rareData()->m_debuggerLineStart != SIZE_MAX) { + ASSERT(interpretedCodeBlock->isOneExpressionOnlyVirtualArrowFunctionExpression()); + context->insertBreakpointAt(interpretedCodeBlock->rareData()->m_debuggerLineStart, this); + } else { + ExtendedNodeLOC sourceElementStart = context->m_codeBlock->functionStart(); + size_t lastLineOffset = context->calculateBreakpointLineOffset(m_loc.index, sourceElementStart); + context->insertBreakpointAt(lastLineOffset + sourceElementStart.line, this); + } } else { insertBreakpoint(context); } diff --git a/lwnode/code/escargotshim/deps/escargot/src/parser/ast/StatementNode.h b/lwnode/code/escargotshim/deps/escargot/src/parser/ast/StatementNode.h index 2119cb6..7beae99 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/parser/ast/StatementNode.h +++ b/lwnode/code/escargotshim/deps/escargot/src/parser/ast/StatementNode.h @@ -31,9 +31,6 @@ public: StatementNode() : Node() , m_nextSibling(nullptr) -#ifdef ESCARGOT_DEBUGGER - , m_line(0) -#endif /* ESCARGOT_DEBUGGER */ { } @@ -74,9 +71,6 @@ public: private: StatementNode* m_nextSibling; -#ifdef ESCARGOT_DEBUGGER - size_t m_line; -#endif /* ESCARGOT_DEBUGGER */ }; class StatementContainer { diff --git a/lwnode/code/escargotshim/deps/escargot/src/parser/esprima_cpp/esprima.cpp b/lwnode/code/escargotshim/deps/escargot/src/parser/esprima_cpp/esprima.cpp index d63fa92..bc035de 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/parser/esprima_cpp/esprima.cpp +++ b/lwnode/code/escargotshim/deps/escargot/src/parser/esprima_cpp/esprima.cpp @@ -1612,7 +1612,7 @@ public: } template - ASTNode parseClassStaticFieldInitializer(ASTBuilder& builder, const AtomicString& className) + ASTNode parseClassStaticFieldInitializer(ASTBuilder& builder, const AtomicString& className, size_t debuggerLineStart) { ASSERT(this->match(Substitution)); @@ -1625,7 +1625,7 @@ public: this->context->allowSuperProperty = true; MetaNode node = this->createNode(); - ASTNode expr = this->parseAssignmentExpressionAndWrapIntoArrowFunction(builder, className); + ASTNode expr = this->parseAssignmentExpressionAndWrapIntoArrowFunction(builder, className, debuggerLineStart); this->consumeSemicolon(); this->context->allowArguments = previousAllowArguments; @@ -1635,7 +1635,7 @@ public: } template - ASTNode parseClassFieldInitializer(ASTBuilder& builder) + ASTNode parseClassFieldInitializer(ASTBuilder& builder, size_t debuggerLineStart) { ASSERT(this->match(Substitution)); @@ -1647,7 +1647,7 @@ public: this->context->allowArguments = false; this->context->allowSuperProperty = true; - ASTNode expr = this->parseAssignmentExpressionAndWrapIntoArrowFunction(builder, AtomicString()); + ASTNode expr = this->parseAssignmentExpressionAndWrapIntoArrowFunction(builder, AtomicString(), debuggerLineStart); this->consumeSemicolon(); this->context->allowArguments = previousAllowArguments; @@ -3410,8 +3410,10 @@ public: } template - ASTNode parseAssignmentExpressionAndWrapIntoArrowFunction(ASTBuilder& builder, const AtomicString& paramName) + ASTNode parseAssignmentExpressionAndWrapIntoArrowFunction(ASTBuilder& builder, const AtomicString& paramName, size_t debuggerLineStart) { + UNUSED_VARIABLE(debuggerLineStart); + ASTNode result; if (!this->isParsingSingleFunction) { BEGIN_FUNCTION_SCANNING(AtomicString()); @@ -3432,6 +3434,10 @@ public: this->currentScopeContext->m_allowSuperCall = this->context->allowSuperCall; this->currentScopeContext->m_allowSuperProperty = this->context->allowSuperProperty; this->currentScopeContext->m_allowArguments = this->context->allowArguments; +#ifdef ESCARGOT_DEBUGGER + this->currentScopeContext->m_needRareData = true; + this->currentScopeContext->m_debuggerLineStart = debuggerLineStart; +#endif /* ESCARGOT_DEBUGGER */ this->isolateCoverGrammar(builder, &Parser::parseAssignmentExpression); auto lastContext = this->lastPoppedScopeContext; @@ -5739,6 +5745,12 @@ public: bool isAsync = false; bool isPrivate = false; +#ifdef ESCARGOT_DEBUGGER + size_t debuggerLineStart = token->lineNumber; +#else /* !ESCARGOT_DEBUGGER */ + size_t debuggerLineStart = 0; +#endif /* ESCARGOT_DEBUGGER */ + if (this->match(Multiply)) { this->nextToken(); } else { @@ -5748,6 +5760,9 @@ public: if (token->type == Token::KeywordToken && (this->qualifiedPropertyName(&this->lookahead) || this->match(Multiply) || this->match(Hash)) && token->relatedSource(this->scanner->source) == "static") { *token = this->lookahead; isStatic = true; +#ifdef ESCARGOT_DEBUGGER + debuggerLineStart = token->lineNumber; +#endif /* ESCARGOT_DEBUGGER */ mayMethodStartNode = this->createNode(); computed = this->match(LeftSquareBracket); if (this->match(Multiply)) { @@ -5809,12 +5824,11 @@ public: } else if (this->match(Substitution)) { if (isStatic) { kind = ClassElementNode::Kind::Field; - value = this->parseClassStaticFieldInitializer(builder, className); + value = this->parseClassStaticFieldInitializer(builder, className, debuggerLineStart); } else { kind = ClassElementNode::Kind::Field; - value = this->parseClassFieldInitializer(builder); + value = this->parseClassFieldInitializer(builder, debuggerLineStart); } - } else if (this->match(SemiColon)) { auto metaNode = this->createNode(); this->nextToken(); diff --git a/lwnode/code/escargotshim/deps/escargot/src/runtime/ArrayObject.cpp b/lwnode/code/escargotshim/deps/escargot/src/runtime/ArrayObject.cpp index 35fb1c0..e72107f 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/runtime/ArrayObject.cpp +++ b/lwnode/code/escargotshim/deps/escargot/src/runtime/ArrayObject.cpp @@ -329,7 +329,7 @@ void ArrayObject::convertIntoNonFastMode(ExecutionState& state) auto length = arrayLength(state); for (size_t i = 0; i < length; i++) { if (!m_fastModeData[i].isEmpty()) { - defineOwnPropertyThrowsExceptionWhenStrictMode(state, ObjectPropertyName(state, Value(i)), ObjectPropertyDescriptor(m_fastModeData[i], ObjectPropertyDescriptor::AllPresent)); + defineOwnPropertyThrowsException(state, ObjectPropertyName(state, Value(i)), ObjectPropertyDescriptor(m_fastModeData[i], ObjectPropertyDescriptor::AllPresent)); } } diff --git a/lwnode/code/escargotshim/deps/escargot/src/runtime/Context.cpp b/lwnode/code/escargotshim/deps/escargot/src/runtime/Context.cpp index efc877a..8a4eb30 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/runtime/Context.cpp +++ b/lwnode/code/escargotshim/deps/escargot/src/runtime/Context.cpp @@ -90,7 +90,7 @@ Context::Context(VMInstance* instance) { ExecutionState stateForInit(this); m_globalObjectProxy = m_globalObject = new GlobalObject(stateForInit); - m_globalObject->installBuiltins(stateForInit); + m_globalObject->initializeBuiltins(stateForInit); } void Context::throwException(ExecutionState& state, const Value& exception) diff --git a/lwnode/code/escargotshim/deps/escargot/src/runtime/EnvironmentRecord.h b/lwnode/code/escargotshim/deps/escargot/src/runtime/EnvironmentRecord.h index 1be3fcc..da5d6f9 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/runtime/EnvironmentRecord.h +++ b/lwnode/code/escargotshim/deps/escargot/src/runtime/EnvironmentRecord.h @@ -240,13 +240,13 @@ public: ObjectPropertyDescriptor::PresentAttribute attribute = (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectStructurePropertyDescriptor::EnumerablePresent); if (canDelete) attribute = (ObjectPropertyDescriptor::PresentAttribute)(attribute | ObjectPropertyDescriptor::ConfigurablePresent); - m_bindingObject->defineOwnPropertyThrowsExceptionWhenStrictMode(state, name, ObjectPropertyDescriptor(Value(), attribute)); + m_bindingObject->defineOwnPropertyThrowsException(state, name, ObjectPropertyDescriptor(Value(), attribute)); } } virtual void initializeBinding(ExecutionState& state, const AtomicString& name, const Value& V) override { - m_bindingObject->defineOwnPropertyThrowsExceptionWhenStrictMode(state, name, ObjectPropertyDescriptor(V, ObjectPropertyDescriptor::AllPresent)); + m_bindingObject->defineOwnPropertyThrowsException(state, name, ObjectPropertyDescriptor(V, ObjectPropertyDescriptor::AllPresent)); } virtual GetBindingValueResult getBindingValue(ExecutionState& state, const AtomicString& name) override diff --git a/lwnode/code/escargotshim/deps/escargot/src/runtime/ErrorObject.cpp b/lwnode/code/escargotshim/deps/escargot/src/runtime/ErrorObject.cpp index 6d69bb2..24c2083 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/runtime/ErrorObject.cpp +++ b/lwnode/code/escargotshim/deps/escargot/src/runtime/ErrorObject.cpp @@ -134,8 +134,8 @@ ErrorObject::ErrorObject(ExecutionState& state, Object* proto, String* errorMess , m_stackTraceData(nullptr) { if (errorMessage->length()) { - defineOwnPropertyThrowsExceptionWhenStrictMode(state, state.context()->staticStrings().message, - ObjectPropertyDescriptor(errorMessage, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectStructurePropertyDescriptor::ConfigurablePresent))); + defineOwnPropertyThrowsException(state, state.context()->staticStrings().message, + ObjectPropertyDescriptor(errorMessage, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectStructurePropertyDescriptor::ConfigurablePresent))); } } diff --git a/lwnode/code/escargotshim/deps/escargot/src/runtime/Global.cpp b/lwnode/code/escargotshim/deps/escargot/src/runtime/Global.cpp index 489961a..46f8e99 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/runtime/Global.cpp +++ b/lwnode/code/escargotshim/deps/escargot/src/runtime/Global.cpp @@ -30,6 +30,10 @@ Platform* Global::g_platform; #if defined(ENABLE_ATOMICS_GLOBAL_LOCK) SpinLock Global::g_atomicsLock; #endif +#if defined(ENABLE_THREADING) +std::mutex Global::g_waiterMutex; +std::vector Global::g_waiter; +#endif void Global::initialize(Platform* platform) { @@ -57,6 +61,14 @@ void Global::finalize() static bool called_once = true; RELEASE_ASSERT(called_once && inited); + +#if defined(ENABLE_THREADING) + for (size_t i = 0; i < g_waiter.size(); i++) { + delete g_waiter[i]; + } + std::vector().swap(g_waiter); +#endif + delete g_platform; g_platform = nullptr; @@ -70,4 +82,22 @@ Platform* Global::platform() return g_platform; } +#if defined(ENABLE_THREADING) +Global::Waiter* Global::waiter(void* blockAddress) +{ + std::lock_guard guard(g_waiterMutex); + for (size_t i = 0; i < g_waiter.size(); i++) { + if (g_waiter[i]->m_blockAddress == blockAddress) { + return g_waiter[i]; + } + } + + Waiter* w = new Waiter(); + w->m_blockAddress = blockAddress; + g_waiter.push_back(w); + + return w; +} +#endif + } // namespace Escargot diff --git a/lwnode/code/escargotshim/deps/escargot/src/runtime/Global.h b/lwnode/code/escargotshim/deps/escargot/src/runtime/Global.h index 38cdd49..3e58407 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/runtime/Global.h +++ b/lwnode/code/escargotshim/deps/escargot/src/runtime/Global.h @@ -20,6 +20,10 @@ #ifndef __EscargotGlobal__ #define __EscargotGlobal__ +#if defined(ENABLE_THREADING) +#include +#endif + #if defined(ENABLE_THREADING) && !defined(HAVE_BUILTIN_ATOMIC_FUNCTIONS) #define ENABLE_ATOMICS_GLOBAL_LOCK #endif @@ -50,6 +54,20 @@ public: return g_atomicsLock; } #endif + +#if defined(ENABLE_THREADING) + struct Waiter { + void* m_blockAddress; + std::mutex m_mutex; + std::condition_variable m_waiter; + std::mutex m_conditionVariableMutex; + std::atomic_uint m_waiterCount; + }; + + static std::mutex g_waiterMutex; + static std::vector g_waiter; + static Waiter* waiter(void* blockAddress); +#endif }; } // namespace Escargot diff --git a/lwnode/code/escargotshim/deps/escargot/src/runtime/GlobalObject.cpp b/lwnode/code/escargotshim/deps/escargot/src/runtime/GlobalObject.cpp index fb9909b..c01cfc4 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/runtime/GlobalObject.cpp +++ b/lwnode/code/escargotshim/deps/escargot/src/runtime/GlobalObject.cpp @@ -46,10 +46,10 @@ namespace Escargot { GlobalObject::GlobalObject(ExecutionState& state) : Object(state, ESCARGOT_OBJECT_BUILTIN_PROPERTY_NUMBER, Object::__ForGlobalBuiltin__) , m_context(state.context()) -#define INIT_BUILTIN_VALUE(builtin, TYPE, NAME) \ +#define INIT_BUILTIN_VALUE(builtin, TYPE, objName) \ , m_##builtin(nullptr) - GLOBALOBJECT_BUILTIN_LIST(INIT_BUILTIN_VALUE) + GLOBALOBJECT_BUILTIN_ALL_LIST(INIT_BUILTIN_VALUE) #undef INIT_BUILTIN_VALUE { // m_objectPrototype should be initialized ahead of any other builtins @@ -59,53 +59,20 @@ GlobalObject::GlobalObject(ExecutionState& state) Object::setGlobalIntrinsicObject(state); } -void GlobalObject::installBuiltins(ExecutionState& state) +void GlobalObject::initializeBuiltins(ExecutionState& state) { // m_objectPrototype has been initialized ahead of any other builtins ASSERT(!!m_objectPrototype); - installFunction(state); - installObject(state); - installIterator(state); - installError(state); - installSymbol(state); - installBigInt(state); - installString(state); - installNumber(state); - installBoolean(state); - installArray(state); - installMath(state); - installDate(state); - installRegExp(state); - installJSON(state); -#if defined(ENABLE_ICU) && defined(ENABLE_INTL) - installIntl(state); -#endif - installPromise(state); - installProxy(state); - installReflect(state); - installArrayBuffer(state); - installDataView(state); - installTypedArray(state); - installMap(state); - installSet(state); - installWeakMap(state); - installWeakRef(state); - installWeakSet(state); - installFinalizationRegistry(state); - installGenerator(state); - installAsyncFunction(state); - installAsyncIterator(state); - installAsyncFromSyncIterator(state); - installAsyncGeneratorFunction(state); -#if defined(ENABLE_THREADING) - installAtomics(state); - installSharedArrayBuffer(state); -#endif -#if defined(ENABLE_WASM) - installWASM(state); -#endif - installOthers(state); + /* + initialize all global builtin properties by calling initialize##objName method + Object, Function and other prerequisite builtins are installed ahead + */ +#define DECLARE_BUILTIN_INIT_FUNC(OBJNAME, objName, ARG) \ + initialize##objName(state); + + GLOBALOBJECT_BUILTIN_OBJECT_LIST(DECLARE_BUILTIN_INIT_FUNC, ) +#undef DECLARE_BUILTIN_INIT_FUNC } Value builtinSpeciesGetter(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) @@ -678,7 +645,6 @@ static Value encode(ExecutionState& state, String* uriString, bool noComponent, } } - size_t newLen = escaped.size(); auto ptr = escaped.takeBuffer(); return new ASCIIString(ptr, newLen, ASCIIString::FromGCBufferTag); @@ -698,7 +664,6 @@ static Value builtinEncodeURIComponent(ExecutionState& state, Value thisValue, s return encode(state, argv[0].toString(state), false, state.context()->staticStrings().encodeURIComponent.string()); } - void char2hex(char dec, URIBuilderString& result) { unsigned char dig1 = (dec & 0xF0) >> 4; @@ -731,7 +696,6 @@ void char2hex4digit(char16_t dec, URIBuilderString& result) } } - static Value builtinEscape(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) { String* str = argv[0].toString(state); @@ -868,182 +832,21 @@ static Value builtinUnescape(ExecutionState& state, Value thisValue, size_t argc } } -// Object.prototype.__defineGetter__ ( P, getter ) -static Value builtinDefineGetter(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - // Let O be ? ToObject(this value). - Object* O = thisValue.toObject(state); - // If IsCallable(getter) is false, throw a TypeError exception. - if (!argv[1].isCallable()) { - ErrorObject::throwBuiltinError(state, ErrorObject::TypeError, String::emptyString, true, state.context()->staticStrings().__defineGetter__.string(), ErrorObject::Messages::GlobalObject_CallbackNotCallable); - } - // Let desc be PropertyDescriptor{[[Get]]: getter, [[Enumerable]]: true, [[Configurable]]: true}. - ObjectPropertyDescriptor desc(JSGetterSetter(argv[1].asObject(), Value(Value::EmptyValue)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::EnumerablePresent | ObjectPropertyDescriptor::ConfigurablePresent)); - - // Let key be ? ToPropertyKey(P). - ObjectPropertyName key(state, argv[0]); - -// Perform ? DefinePropertyOrThrow(O, key, desc). -#if defined(ENABLE_V8_LIKE_DEFINE_LOOKUP_GETTER_SETTER) - O->defineOwnProperty(state, key, desc); -#else - O->defineOwnPropertyThrowsException(state, key, desc); -#endif - - // Return undefined. - return Value(); -} - -// Object.prototype.__defineSetter__ ( P, getter ) -static Value builtinDefineSetter(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - // Let O be ? ToObject(this value). - Object* O = thisValue.toObject(state); - // If IsCallable(getter) is false, throw a TypeError exception. - if (!argv[1].isCallable()) { - ErrorObject::throwBuiltinError(state, ErrorObject::TypeError, String::emptyString, true, state.context()->staticStrings().__defineSetter__.string(), ErrorObject::Messages::GlobalObject_CallbackNotCallable); - } - // Let desc be PropertyDescriptor{[[Get]]: getter, [[Enumerable]]: true, [[Configurable]]: true}. - ObjectPropertyDescriptor desc(JSGetterSetter(Value(Value::EmptyValue), argv[1].asObject()), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::EnumerablePresent | ObjectPropertyDescriptor::ConfigurablePresent)); - - // Let key be ? ToPropertyKey(P). - ObjectPropertyName key(state, argv[0]); - -// Perform ? DefinePropertyOrThrow(O, key, desc). -#if defined(ENABLE_V8_LIKE_DEFINE_LOOKUP_GETTER_SETTER) - O->defineOwnProperty(state, key, desc); -#else - O->defineOwnPropertyThrowsException(state, key, desc); -#endif - - // Return undefined. - return Value(); -} - -// Object.prototype.__lookupGetter__ ( P, getter ) -static Value builtinLookupGetter(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - // Let O be ? ToObject(this value). - Object* O = thisValue.toObject(state); - // Let key be ? ToPropertyKey(P). - ObjectPropertyName key(state, argv[0]); - - // Repeat, - while (O) { - // Let desc be ? O.[[GetOwnProperty]](key). - auto desc = O->getOwnProperty(state, key); - - // If desc is not undefined, then - if (desc.hasValue()) { - // If IsAccessorDescriptor(desc) is true, return desc.[[Get]]. - if (!desc.isDataProperty() && desc.jsGetterSetter()->hasGetter()) { - return desc.jsGetterSetter()->getter(); - } - // Return undefined. - return Value(); - } - // Set O to ? O.[[GetPrototypeOf]](). - O = O->getPrototypeObject(state); - // If O is null, return undefined. - } - return Value(); -} - -// Object.prototype.__lookupSetter__ ( P, getter ) -static Value builtinLookupSetter(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) +static Value builtinArrayToString(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) { - // Let O be ? ToObject(this value). - Object* O = thisValue.toObject(state); - // Let key be ? ToPropertyKey(P). - ObjectPropertyName key(state, argv[0]); - - // Repeat, - while (O) { - // Let desc be ? O.[[GetOwnProperty]](key). - auto desc = O->getOwnProperty(state, key); - - // If desc is not undefined, then - if (desc.hasValue()) { - // If IsAccessorDescriptor(desc) is true, return desc.[[Set]]. - if (!desc.isDataProperty() && desc.jsGetterSetter()->hasSetter()) { - return desc.jsGetterSetter()->setter(); - } - // Return undefined. - return Value(); - } - // Set O to ? O.[[GetPrototypeOf]](). - O = O->getPrototypeObject(state); - // If O is null, return undefined. + // this builtin function is shared both for Array and TypedArray (prototype.toString property) + RESOLVE_THIS_BINDING_TO_OBJECT(thisObject, Array, toString); + Value toString = thisObject->get(state, state.context()->staticStrings().join).value(state, thisObject); + if (!toString.isCallable()) { + toString = state.context()->globalObject()->objectPrototypeToString(); } - return Value(); + return Object::call(state, toString, thisObject, 0, nullptr); } -static Value builtinCallerAndArgumentsGetterSetter(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) +void GlobalObject::initializeOthers(ExecutionState& state) { - FunctionObject* targetFunction = nullptr; - bool needThrow = false; - if (thisValue.isCallable()) { - if (thisValue.isFunction()) { - targetFunction = thisValue.asFunction(); - if (targetFunction->isScriptFunctionObject()) { - InterpretedCodeBlock* codeBlock = targetFunction->asScriptFunctionObject()->interpretedCodeBlock(); - if (codeBlock->isStrict() || codeBlock->isArrowFunctionExpression() || codeBlock->isGenerator()) { - needThrow = true; - } - } else { - ASSERT(targetFunction->isNativeFunctionObject()); - if (targetFunction->asNativeFunctionObject()->nativeCodeBlock()->isStrict()) { - needThrow = true; - } - } - } else if (thisValue.isObject()) { - auto object = thisValue.asObject(); - if (object->isBoundFunctionObject()) { - needThrow = true; - } - } - } else if (!thisValue.isPrimitive() && !thisValue.isObject()) { - needThrow = true; - } - - if (needThrow) { - ErrorObject::throwBuiltinError(state, ErrorObject::TypeError, "'caller' and 'arguments' restrict properties may not be accessed on strict mode functions or the arguments objects for calls to them"); - } - - bool inStrict = false; - - ExecutionState* p = state.parent(); - while (p) { - if (p->inStrictMode()) { - inStrict = true; - break; - } - p = p->parent(); - } - - if (targetFunction && !inStrict) { - bool foundTargetFunction = false; - ExecutionState* p = &state; - while (p) { - if (foundTargetFunction) { - auto callee = p->resolveCallee(); - if (callee != targetFunction) { - if (callee) { - return Value(callee); - } else { - return Value(Value::Null); - } - } - } else { - if (p->resolveCallee() == targetFunction) { - foundTargetFunction = true; - } - } - p = p->parent(); - } - } - - return Value(Value::Null); + // Other prerequisite builtins should be installed at the start time + installOthers(state); } void GlobalObject::installOthers(ExecutionState& state) @@ -1056,8 +859,10 @@ void GlobalObject::installOthers(ExecutionState& state) // $18.2.1 eval (x) m_eval = new NativeFunctionObject(state, NativeFunctionInfo(strings->eval, builtinEval, 1, NativeFunctionInfo::Strict)); + defineOwnProperty(state, ObjectPropertyName(strings->eval), ObjectPropertyDescriptor(m_eval, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); + // $18.2.2 isFinite(number) defineOwnProperty(state, ObjectPropertyName(strings->isFinite), ObjectPropertyDescriptor(new NativeFunctionObject(state, @@ -1068,25 +873,6 @@ void GlobalObject::installOthers(ExecutionState& state) ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->isNaN, builtinIsNaN, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - FunctionObject* parseInt = new NativeFunctionObject(state, NativeFunctionInfo(strings->parseInt, builtinParseInt, 2, NativeFunctionInfo::Strict)); - defineOwnProperty(state, ObjectPropertyName(strings->parseInt), - ObjectPropertyDescriptor(parseInt, - (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - m_number->defineOwnProperty(state, ObjectPropertyName(strings->parseInt), - ObjectPropertyDescriptor(parseInt, - (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - FunctionObject* parseFloat = new NativeFunctionObject(state, NativeFunctionInfo(strings->parseFloat, builtinParseFloat, 1, NativeFunctionInfo::Strict)); - defineOwnProperty(state, ObjectPropertyName(strings->parseFloat), - ObjectPropertyDescriptor(parseFloat, - (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - m_number->defineOwnProperty(state, ObjectPropertyName(strings->parseFloat), - ObjectPropertyDescriptor(parseFloat, - (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - defineOwnProperty(state, ObjectPropertyName(strings->encodeURI), ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->encodeURI, builtinEncodeURI, 1, NativeFunctionInfo::Strict)), @@ -1117,31 +903,33 @@ void GlobalObject::installOthers(ExecutionState& state) NativeFunctionInfo(strings->unescape, builtinUnescape, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - auto defineLookupGetterSetterNativeFunctionFlag = -#if defined(ENABLE_V8_LIKE_DEFINE_LOOKUP_GETTER_SETTER) - 0; -#else - NativeFunctionInfo::Strict; -#endif - m_objectPrototype->defineOwnProperty(state, ObjectPropertyName(strings->__defineGetter__), - ObjectPropertyDescriptor(new NativeFunctionObject(state, - NativeFunctionInfo(strings->__defineGetter__, builtinDefineGetter, 2, defineLookupGetterSetterNativeFunctionFlag)), - (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - m_objectPrototype->defineOwnProperty(state, ObjectPropertyName(strings->__defineSetter__), - ObjectPropertyDescriptor(new NativeFunctionObject(state, - NativeFunctionInfo(strings->__defineSetter__, builtinDefineSetter, 2, defineLookupGetterSetterNativeFunctionFlag)), - (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - m_objectPrototype->defineOwnProperty(state, ObjectPropertyName(strings->__lookupGetter__), - ObjectPropertyDescriptor(new NativeFunctionObject(state, - NativeFunctionInfo(strings->__lookupGetter__, builtinLookupGetter, 1, defineLookupGetterSetterNativeFunctionFlag)), - (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - m_objectPrototype->defineOwnProperty(state, ObjectPropertyName(strings->__lookupSetter__), - ObjectPropertyDescriptor(new NativeFunctionObject(state, - NativeFunctionInfo(strings->__lookupSetter__, builtinLookupSetter, 1, defineLookupGetterSetterNativeFunctionFlag)), - (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); + // shared builtin methods + m_parseInt = new NativeFunctionObject(state, NativeFunctionInfo(strings->parseInt, builtinParseInt, 2, NativeFunctionInfo::Strict)); + defineOwnProperty(state, ObjectPropertyName(strings->parseInt), + ObjectPropertyDescriptor(m_parseInt, + (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); + + m_parseFloat = new NativeFunctionObject(state, NativeFunctionInfo(strings->parseFloat, builtinParseFloat, 1, NativeFunctionInfo::Strict)); + defineOwnProperty(state, ObjectPropertyName(strings->parseFloat), + ObjectPropertyDescriptor(m_parseFloat, + (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); + + m_arrayToString = new NativeFunctionObject(state, NativeFunctionInfo(strings->toString, builtinArrayToString, 0, NativeFunctionInfo::Strict)); + + // shared builtin objects + m_asyncIteratorPrototype = new Object(state); + m_asyncIteratorPrototype->setGlobalIntrinsicObject(state, true); + // https://www.ecma-international.org/ecma-262/10.0/index.html#sec-asynciteratorprototype-asynciterator + m_asyncIteratorPrototype->defineOwnPropertyThrowsException(state, ObjectPropertyName(state.context()->vmInstance()->globalSymbols().asyncIterator), + ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(AtomicString(state, String::fromASCII("[Symbol.asyncIterator]")), builtinSpeciesGetter, 0, NativeFunctionInfo::Strict)), + (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); + + m_iteratorPrototype = new Object(state); + m_iteratorPrototype->setGlobalIntrinsicObject(state, true); + // https://www.ecma-international.org/ecma-262/10.0/index.html#sec-%iteratorprototype%-@@iterator + m_iteratorPrototype->defineOwnPropertyThrowsException(state, ObjectPropertyName(state.context()->vmInstance()->globalSymbols().iterator), + ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(AtomicString(state, String::fromASCII("[Symbol.iterator]")), builtinSpeciesGetter, 0, NativeFunctionInfo::Strict)), + (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); #if defined(ESCARGOT_ENABLE_TEST) AtomicString isFunctionAllocatedOnStackFunctionName(state, "isFunctionAllocatedOnStack"); @@ -1175,23 +963,6 @@ void GlobalObject::installOthers(ExecutionState& state) (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::AllPresent))); #endif - m_stringProxyObject = new StringObject(state); - m_numberProxyObject = new NumberObject(state); - m_booleanProxyObject = new BooleanObject(state); - m_symbolProxyObject = new SymbolObject(state, state.context()->vmInstance()->globalSymbols().iterator); - m_bigIntProxyObject = new BigIntObject(state, new BigInt(UINT64_C(0))); - - // 8.2.2 - 12 - // AddRestrictedFunctionProperties(funcProto, realmRec). - auto fn = new NativeFunctionObject(state, NativeFunctionInfo(state.context()->staticStrings().caller, builtinCallerAndArgumentsGetterSetter, 0, NativeFunctionInfo::Strict)); - JSGetterSetter gs(fn, fn); - ObjectPropertyDescriptor desc(gs, ObjectPropertyDescriptor::ConfigurablePresent); - m_functionPrototype->defineOwnPropertyThrowsException(state, ObjectPropertyName(state.context()->staticStrings().caller), desc); - m_functionPrototype->defineOwnPropertyThrowsException(state, ObjectPropertyName(state.context()->staticStrings().arguments), desc); - - m_generator->defineOwnPropertyThrowsException(state, ObjectPropertyName(state.context()->staticStrings().caller), desc); - m_generator->defineOwnPropertyThrowsException(state, ObjectPropertyName(state.context()->staticStrings().arguments), desc); - // https://tc39.es/ecma262/#sec-globalthis // The initial value of globalThis is the well-known intrinsic object %GlobalThisValue%. // This property has the attributes { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }. diff --git a/lwnode/code/escargotshim/deps/escargot/src/runtime/GlobalObject.h b/lwnode/code/escargotshim/deps/escargot/src/runtime/GlobalObject.h index 8368f98..831ce11 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/runtime/GlobalObject.h +++ b/lwnode/code/escargotshim/deps/escargot/src/runtime/GlobalObject.h @@ -40,248 +40,252 @@ class FunctionObject; String* NAME = thisValue.toString(state); -#define GLOBALOBJECT_BUILTIN_ARRAYBUFFER(F, NAME) \ - F(arrayBuffer, FunctionObject, NAME) \ - F(arrayBufferPrototype, Object, NAME) -#define GLOBALOBJECT_BUILTIN_ARRAY(F, NAME) \ - F(array, FunctionObject, NAME) \ - F(arrayPrototype, Object, NAME) \ - F(arrayIteratorPrototype, Object, NAME) \ - F(arrayPrototypeValues, FunctionObject, NAME) -#define GLOBALOBJECT_BUILTIN_ASYNCFROMSYNCITERATOR(F, NAME) \ - F(asyncFromSyncIteratorPrototype, Object, NAME) -#define GLOBALOBJECT_BUILTIN_ASYNCFUNCTION(F, NAME) \ - F(asyncFunction, FunctionObject, NAME) \ - F(asyncFunctionPrototype, Object, NAME) -#define GLOBALOBJECT_BUILTIN_ASYNCGENERATOR(F, NAME) \ - F(asyncGenerator, Object, NAME) \ - F(asyncGeneratorPrototype, Object, NAME) \ - F(asyncGeneratorFunction, FunctionObject, NAME) -#define GLOBALOBJECT_BUILTIN_ASYNCITERATOR(F, NAME) \ - F(asyncIteratorPrototype, Object, NAME) -#define GLOBALOBJECT_BUILTIN_BOOLEAN(F, NAME) \ - F(boolean, FunctionObject, NAME) \ - F(booleanPrototype, Object, NAME) -#define GLOBALOBJECT_BUILTIN_DATAVIEW(F, NAME) \ - F(dataView, FunctionObject, NAME) \ - F(dataViewPrototype, Object, NAME) -#define GLOBALOBJECT_BUILTIN_DATE(F, NAME) \ - F(date, FunctionObject, NAME) \ - F(datePrototype, Object, NAME) -#define GLOBALOBJECT_BUILTIN_ERROR(F, NAME) \ - F(error, FunctionObject, NAME) \ - F(errorPrototype, Object, NAME) \ - F(referenceError, FunctionObject, NAME) \ - F(referenceErrorPrototype, Object, NAME) \ - F(typeError, FunctionObject, NAME) \ - F(typeErrorPrototype, Object, NAME) \ - F(rangeError, FunctionObject, NAME) \ - F(rangeErrorPrototype, Object, NAME) \ - F(syntaxError, FunctionObject, NAME) \ - F(syntaxErrorPrototype, Object, NAME) \ - F(uriError, FunctionObject, NAME) \ - F(uriErrorPrototype, Object, NAME) \ - F(evalError, FunctionObject, NAME) \ - F(evalErrorPrototype, Object, NAME) \ - F(aggregateError, FunctionObject, NAME) \ - F(aggregateErrorPrototype, Object, NAME) \ - F(throwTypeError, FunctionObject, NAME) \ - F(throwerGetterSetterData, JSGetterSetter, NAME) -#define GLOBALOBJECT_BUILTIN_EVAL(F, NAME) \ - F(eval, FunctionObject, NAME) -#define GLOBALOBJECT_BUILTIN_FUNCTION(F, NAME) \ - F(function, FunctionObject, NAME) \ - F(functionPrototype, FunctionObject, NAME) \ - F(functionApply, FunctionObject, NAME) -#define GLOBALOBJECT_BUILTIN_GENERATOR(F, NAME) \ - F(generatorFunction, FunctionObject, NAME) \ - F(generator, FunctionObject, NAME) \ - F(generatorPrototype, Object, NAME) +#define GLOBALOBJECT_BUILTIN_ARRAYBUFFER(F, objName) \ + F(arrayBuffer, FunctionObject, objName) \ + F(arrayBufferPrototype, Object, objName) +#define GLOBALOBJECT_BUILTIN_ARRAY(F, objName) \ + F(array, FunctionObject, objName) \ + F(arrayPrototype, Object, objName) \ + F(arrayIteratorPrototype, Object, objName) \ + F(arrayPrototypeValues, FunctionObject, objName) +#define GLOBALOBJECT_BUILTIN_ASYNCFROMSYNCITERATOR(F, objName) \ + F(asyncFromSyncIteratorPrototype, Object, objName) +#define GLOBALOBJECT_BUILTIN_ASYNCFUNCTION(F, objName) \ + F(asyncFunction, FunctionObject, objName) \ + F(asyncFunctionPrototype, Object, objName) +#define GLOBALOBJECT_BUILTIN_ASYNCGENERATOR(F, objName) \ + F(asyncGenerator, Object, objName) \ + F(asyncGeneratorPrototype, Object, objName) \ + F(asyncGeneratorFunction, FunctionObject, objName) +#define GLOBALOBJECT_BUILTIN_BOOLEAN(F, objName) \ + F(boolean, FunctionObject, objName) \ + F(booleanPrototype, Object, objName) \ + F(booleanProxyObject, BooleanObject, objName) +#define GLOBALOBJECT_BUILTIN_DATAVIEW(F, objName) \ + F(dataView, FunctionObject, objName) \ + F(dataViewPrototype, Object, objName) +#define GLOBALOBJECT_BUILTIN_DATE(F, objName) \ + F(date, FunctionObject, objName) \ + F(datePrototype, Object, objName) +#define GLOBALOBJECT_BUILTIN_ERROR(F, objName) \ + F(error, FunctionObject, objName) \ + F(errorPrototype, Object, objName) \ + F(referenceError, FunctionObject, objName) \ + F(referenceErrorPrototype, Object, objName) \ + F(typeError, FunctionObject, objName) \ + F(typeErrorPrototype, Object, objName) \ + F(rangeError, FunctionObject, objName) \ + F(rangeErrorPrototype, Object, objName) \ + F(syntaxError, FunctionObject, objName) \ + F(syntaxErrorPrototype, Object, objName) \ + F(uriError, FunctionObject, objName) \ + F(uriErrorPrototype, Object, objName) \ + F(evalError, FunctionObject, objName) \ + F(evalErrorPrototype, Object, objName) \ + F(aggregateError, FunctionObject, objName) \ + F(aggregateErrorPrototype, Object, objName) \ + F(throwTypeError, FunctionObject, objName) \ + F(throwerGetterSetterData, JSGetterSetter, objName) +#define GLOBALOBJECT_BUILTIN_FUNCTION(F, objName) \ + F(function, FunctionObject, objName) \ + F(functionPrototype, FunctionObject, objName) \ + F(functionApply, FunctionObject, objName) \ + F(callerAndArgumentsGetterSetter, FunctionObject, objName) +#define GLOBALOBJECT_BUILTIN_GENERATOR(F, objName) \ + F(generatorFunction, FunctionObject, objName) \ + F(generator, FunctionObject, objName) \ + F(generatorPrototype, Object, objName) //INTL #if defined(ENABLE_ICU) && defined(ENABLE_INTL) -#define GLOBALOBJECT_BUILTIN_INTL(F, NAME) \ - F(intl, Object, NAME) \ - F(intlCollator, FunctionObject, NAME) \ - F(intlDateTimeFormat, FunctionObject, NAME) \ - F(intlDateTimeFormatPrototype, Object, NAME) \ - F(intlNumberFormat, FunctionObject, NAME) \ - F(intlNumberFormatPrototype, Object, NAME) \ - F(intlRelativeTimeFormat, FunctionObject, NAME) \ - F(intlRelativeTimeFormatPrototype, Object, NAME) \ - F(intlLocale, FunctionObject, NAME) \ - F(intlLocalePrototype, Object, NAME) \ - F(intlPluralRules, FunctionObject, NAME) \ - F(intlPluralRulesPrototype, Object, NAME) +#define GLOBALOBJECT_BUILTIN_INTL(F, objName) \ + F(intl, Object, objName) \ + F(intlCollator, FunctionObject, objName) \ + F(intlDateTimeFormat, FunctionObject, objName) \ + F(intlDateTimeFormatPrototype, Object, objName) \ + F(intlNumberFormat, FunctionObject, objName) \ + F(intlNumberFormatPrototype, Object, objName) \ + F(intlRelativeTimeFormat, FunctionObject, objName) \ + F(intlRelativeTimeFormatPrototype, Object, objName) \ + F(intlLocale, FunctionObject, objName) \ + F(intlLocalePrototype, Object, objName) \ + F(intlPluralRules, FunctionObject, objName) \ + F(intlPluralRulesPrototype, Object, objName) #else -#define GLOBALOBJECT_BUILTIN_INTL(F, NAME) +#define GLOBALOBJECT_BUILTIN_INTL(F, objName) #endif -#define GLOBALOBJECT_BUILTIN_ITERATOR(F, NAME) \ - F(iteratorPrototype, Object, NAME) -#define GLOBALOBJECT_BUILTIN_JSON(F, NAME) \ - F(json, Object, NAME) \ - F(jsonStringify, FunctionObject, NAME) \ - F(jsonParse, FunctionObject, NAME) -#define GLOBALOBJECT_BUILTIN_MAP(F, NAME) \ - F(map, FunctionObject, NAME) \ - F(mapPrototype, Object, NAME) \ - F(mapIteratorPrototype, Object, NAME) -#define GLOBALOBJECT_BUILTIN_MATH(F, NAME) \ - F(math, Object, NAME) -#define GLOBALOBJECT_BUILTIN_NUMBER(F, NAME) \ - F(number, FunctionObject, NAME) \ - F(numberPrototype, Object, NAME) -#define GLOBALOBJECT_BUILTIN_OBJECT(F, NAME) \ - F(object, FunctionObject, NAME) \ - F(objectCreate, FunctionObject, NAME) \ - F(objectFreeze, FunctionObject, NAME) \ - F(objectPrototype, Object, NAME) \ - F(objectPrototypeToString, FunctionObject, NAME) -#define GLOBALOBJECT_BUILTIN_OTHERS(F, NAME) \ - F(stringProxyObject, StringObject, NAME) \ - F(numberProxyObject, NumberObject, NAME) \ - F(booleanProxyObject, BooleanObject, NAME) \ - F(symbolProxyObject, SymbolObject, NAME) \ - F(bigIntProxyObject, BigIntObject, NAME) -#define GLOBALOBJECT_BUILTIN_PROMISE(F, NAME) \ - F(promise, FunctionObject, NAME) \ - F(promisePrototype, Object, NAME) -#define GLOBALOBJECT_BUILTIN_PROXY(F, NAME) \ - F(proxy, FunctionObject, NAME) -#define GLOBALOBJECT_BUILTIN_REFLECT(F, NAME) \ - F(reflect, Object, NAME) -#define GLOBALOBJECT_BUILTIN_REGEXP(F, NAME) \ - F(regexp, FunctionObject, NAME) \ - F(regexpExecMethod, FunctionObject, NAME) \ - F(regexpPrototype, Object, NAME) \ - F(regexpReplaceMethod, FunctionObject, NAME) \ - F(regexpStringIteratorPrototype, Object, NAME) \ - F(regexpSplitMethod, FunctionObject, NAME) -#define GLOBALOBJECT_BUILTIN_SET(F, NAME) \ - F(set, FunctionObject, NAME) \ - F(setPrototype, Object, NAME) \ - F(setIteratorPrototype, Object, NAME) -#define GLOBALOBJECT_BUILTIN_STRING(F, NAME) \ - F(string, FunctionObject, NAME) \ - F(stringPrototype, Object, NAME) \ - F(stringIteratorPrototype, Object, NAME) -#define GLOBALOBJECT_BUILTIN_SYMBOL(F, NAME) \ - F(symbol, FunctionObject, NAME) \ - F(symbolPrototype, Object, NAME) -#define GLOBALOBJECT_BUILTIN_BIGINT(F, NAME) \ - F(bigInt, FunctionObject, NAME) \ - F(bigIntPrototype, Object, NAME) -#define GLOBALOBJECT_BUILTIN_TYPEDARRAY(F, NAME) \ - F(typedArray, FunctionObject, NAME) \ - F(typedArrayPrototype, Object, NAME) \ - F(int8Array, FunctionObject, NAME) \ - F(int8ArrayPrototype, Object, NAME) \ - F(uint8Array, FunctionObject, NAME) \ - F(uint8ArrayPrototype, Object, NAME) \ - F(uint8ClampedArray, FunctionObject, NAME) \ - F(uint8ClampedArrayPrototype, Object, NAME) \ - F(int16Array, FunctionObject, NAME) \ - F(int16ArrayPrototype, Object, NAME) \ - F(uint16Array, FunctionObject, NAME) \ - F(uint16ArrayPrototype, Object, NAME) \ - F(int32Array, FunctionObject, NAME) \ - F(int32ArrayPrototype, Object, NAME) \ - F(uint32Array, FunctionObject, NAME) \ - F(uint32ArrayPrototype, Object, NAME) \ - F(float32Array, FunctionObject, NAME) \ - F(float32ArrayPrototype, Object, NAME) \ - F(float64Array, FunctionObject, NAME) \ - F(float64ArrayPrototype, Object, NAME) \ - F(bigInt64Array, FunctionObject, NAME) \ - F(bigInt64ArrayPrototype, Object, NAME) \ - F(bigUint64Array, FunctionObject, NAME) \ - F(bigUint64ArrayPrototype, Object, NAME) -#define GLOBALOBJECT_BUILTIN_WEAKMAP(F, NAME) \ - F(weakMap, FunctionObject, NAME) \ - F(weakMapPrototype, Object, NAME) -#define GLOBALOBJECT_BUILTIN_WEAKSET(F, NAME) \ - F(weakSet, FunctionObject, NAME) \ - F(weakSetPrototype, Object, NAME) -#define GLOBALOBJECT_BUILTIN_WEAKREF(F, NAME) \ - F(weakRef, FunctionObject, NAME) \ - F(weakRefPrototype, Object, NAME) -#define GLOBALOBJECT_BUILTIN_FINALIZATIONREGISTRY(F, NAME) \ - F(finalizationRegistry, FunctionObject, NAME) \ - F(finalizationRegistryPrototype, Object, NAME) +#define GLOBALOBJECT_BUILTIN_JSON(F, objName) \ + F(json, Object, objName) \ + F(jsonStringify, FunctionObject, objName) \ + F(jsonParse, FunctionObject, objName) +#define GLOBALOBJECT_BUILTIN_MAP(F, objName) \ + F(map, FunctionObject, objName) \ + F(mapPrototype, Object, objName) \ + F(mapIteratorPrototype, Object, objName) +#define GLOBALOBJECT_BUILTIN_MATH(F, objName) \ + F(math, Object, objName) +#define GLOBALOBJECT_BUILTIN_NUMBER(F, objName) \ + F(number, FunctionObject, objName) \ + F(numberPrototype, Object, objName) \ + F(numberProxyObject, NumberObject, objName) +#define GLOBALOBJECT_BUILTIN_OBJECT(F, objName) \ + F(object, FunctionObject, objName) \ + F(objectCreate, FunctionObject, objName) \ + F(objectFreeze, FunctionObject, objName) \ + F(objectPrototype, Object, objName) \ + F(objectPrototypeToString, FunctionObject, objName) +#define GLOBALOBJECT_BUILTIN_OTHERS(F, objName) \ + F(eval, FunctionObject, objName) \ + F(parseInt, FunctionObject, objName) \ + F(parseFloat, FunctionObject, objName) \ + F(arrayToString, FunctionObject, objName) \ + F(asyncIteratorPrototype, Object, objName) \ + F(iteratorPrototype, Object, objName) +#define GLOBALOBJECT_BUILTIN_PROMISE(F, objName) \ + F(promise, FunctionObject, objName) \ + F(promisePrototype, Object, objName) +#define GLOBALOBJECT_BUILTIN_PROXY(F, objName) \ + F(proxy, FunctionObject, objName) +#define GLOBALOBJECT_BUILTIN_REFLECT(F, objName) \ + F(reflect, Object, objName) +#define GLOBALOBJECT_BUILTIN_REGEXP(F, objName) \ + F(regexp, FunctionObject, objName) \ + F(regexpExecMethod, FunctionObject, objName) \ + F(regexpPrototype, Object, objName) \ + F(regexpReplaceMethod, FunctionObject, objName) \ + F(regexpStringIteratorPrototype, Object, objName) \ + F(regexpSplitMethod, FunctionObject, objName) +#define GLOBALOBJECT_BUILTIN_SET(F, objName) \ + F(set, FunctionObject, objName) \ + F(setPrototype, Object, objName) \ + F(setIteratorPrototype, Object, objName) +#define GLOBALOBJECT_BUILTIN_STRING(F, objName) \ + F(string, FunctionObject, objName) \ + F(stringPrototype, Object, objName) \ + F(stringIteratorPrototype, Object, objName) \ + F(stringProxyObject, StringObject, objName) +#define GLOBALOBJECT_BUILTIN_SYMBOL(F, objName) \ + F(symbol, FunctionObject, objName) \ + F(symbolPrototype, Object, objName) \ + F(symbolProxyObject, SymbolObject, objName) +#define GLOBALOBJECT_BUILTIN_BIGINT(F, objName) \ + F(bigInt, FunctionObject, objName) \ + F(bigIntPrototype, Object, objName) \ + F(bigIntProxyObject, BigIntObject, objName) +#define GLOBALOBJECT_BUILTIN_TYPEDARRAY(F, objName) \ + F(typedArray, FunctionObject, objName) \ + F(typedArrayPrototype, Object, objName) \ + F(int8Array, FunctionObject, objName) \ + F(int8ArrayPrototype, Object, objName) \ + F(uint8Array, FunctionObject, objName) \ + F(uint8ArrayPrototype, Object, objName) \ + F(uint8ClampedArray, FunctionObject, objName) \ + F(uint8ClampedArrayPrototype, Object, objName) \ + F(int16Array, FunctionObject, objName) \ + F(int16ArrayPrototype, Object, objName) \ + F(uint16Array, FunctionObject, objName) \ + F(uint16ArrayPrototype, Object, objName) \ + F(int32Array, FunctionObject, objName) \ + F(int32ArrayPrototype, Object, objName) \ + F(uint32Array, FunctionObject, objName) \ + F(uint32ArrayPrototype, Object, objName) \ + F(float32Array, FunctionObject, objName) \ + F(float32ArrayPrototype, Object, objName) \ + F(float64Array, FunctionObject, objName) \ + F(float64ArrayPrototype, Object, objName) \ + F(bigInt64Array, FunctionObject, objName) \ + F(bigInt64ArrayPrototype, Object, objName) \ + F(bigUint64Array, FunctionObject, objName) \ + F(bigUint64ArrayPrototype, Object, objName) +#define GLOBALOBJECT_BUILTIN_WEAKMAP(F, objName) \ + F(weakMap, FunctionObject, objName) \ + F(weakMapPrototype, Object, objName) +#define GLOBALOBJECT_BUILTIN_WEAKSET(F, objName) \ + F(weakSet, FunctionObject, objName) \ + F(weakSetPrototype, Object, objName) +#define GLOBALOBJECT_BUILTIN_WEAKREF(F, objName) \ + F(weakRef, FunctionObject, objName) \ + F(weakRefPrototype, Object, objName) +#define GLOBALOBJECT_BUILTIN_FINALIZATIONREGISTRY(F, objName) \ + F(finalizationRegistry, FunctionObject, objName) \ + F(finalizationRegistryPrototype, Object, objName) #if defined(ENABLE_THREADING) -#define GLOBALOBJECT_BUILTIN_ATOMICS(F, NAME) \ - F(atomics, Object, Name) -#define GLOBALOBJECT_BUILTIN_SHAREDARRAYBUFFER(F, NAME) \ - F(sharedArrayBuffer, FunctionObject, Name) \ - F(sharedArrayBufferPrototype, Object, Name) +#define GLOBALOBJECT_BUILTIN_ATOMICS(F, objName) \ + F(atomics, Object, objName) +#define GLOBALOBJECT_BUILTIN_SHAREDARRAYBUFFER(F, objName) \ + F(sharedArrayBuffer, FunctionObject, objName) \ + F(sharedArrayBufferPrototype, Object, objName) #else -#define GLOBALOBJECT_BUILTIN_ATOMICS(F, NAME) -#define GLOBALOBJECT_BUILTIN_SHAREDARRAYBUFFER(F, NAME) +#define GLOBALOBJECT_BUILTIN_ATOMICS(F, objName) +#define GLOBALOBJECT_BUILTIN_SHAREDARRAYBUFFER(F, objName) #endif //WebAssembly #if defined(ENABLE_WASM) -#define GLOBALOBJECT_BUILTIN_WASM(F, NAME) \ - F(wasmModulePrototype, Object, Name) \ - F(wasmInstancePrototype, Object, Name) \ - F(wasmMemoryPrototype, Object, Name) \ - F(wasmTablePrototype, Object, Name) \ - F(wasmGlobalPrototype, Object, Name) \ - F(wasmCompileErrorPrototype, Object, NAME) \ - F(wasmLinkErrorPrototype, Object, NAME) \ - F(wasmRuntimeErrorPrototype, Object, NAME) +#define GLOBALOBJECT_BUILTIN_WASM(F, objName) \ + F(wasm, Object, objName) \ + F(wasmModulePrototype, Object, objName) \ + F(wasmInstancePrototype, Object, objName) \ + F(wasmMemoryPrototype, Object, objName) \ + F(wasmTablePrototype, Object, objName) \ + F(wasmGlobalPrototype, Object, objName) \ + F(wasmCompileErrorPrototype, Object, objName) \ + F(wasmLinkErrorPrototype, Object, objName) \ + F(wasmRuntimeErrorPrototype, Object, objName) #else -#define GLOBALOBJECT_BUILTIN_WASM(F, NAME) +#define GLOBALOBJECT_BUILTIN_WASM(F, objName) #endif -#define GLOBALOBJECT_BUILTIN_LIST(F) \ - GLOBALOBJECT_BUILTIN_ARRAYBUFFER(F, ArrayBuffer) \ - GLOBALOBJECT_BUILTIN_ARRAY(F, Array) \ - GLOBALOBJECT_BUILTIN_ASYNCFROMSYNCITERATOR(F, AsyncFromSyncIterator) \ - GLOBALOBJECT_BUILTIN_ASYNCFUNCTION(F, AsyncFunction) \ - GLOBALOBJECT_BUILTIN_ASYNCGENERATOR(F, AsyncGenerator) \ - GLOBALOBJECT_BUILTIN_ASYNCITERATOR(F, AsyncIterator) \ - GLOBALOBJECT_BUILTIN_ATOMICS(F, Atomics) \ - GLOBALOBJECT_BUILTIN_BOOLEAN(F, Boolean) \ - GLOBALOBJECT_BUILTIN_DATAVIEW(F, DataView) \ - GLOBALOBJECT_BUILTIN_DATE(F, Date) \ - GLOBALOBJECT_BUILTIN_ERROR(F, Error) \ - GLOBALOBJECT_BUILTIN_EVAL(F, Eval) \ - GLOBALOBJECT_BUILTIN_FUNCTION(F, Function) \ - GLOBALOBJECT_BUILTIN_GENERATOR(F, Generator) \ - GLOBALOBJECT_BUILTIN_INTL(F, Intl) \ - GLOBALOBJECT_BUILTIN_ITERATOR(F, Iterator) \ - GLOBALOBJECT_BUILTIN_JSON(F, JSON) \ - GLOBALOBJECT_BUILTIN_MAP(F, Map) \ - GLOBALOBJECT_BUILTIN_MATH(F, Math) \ - GLOBALOBJECT_BUILTIN_NUMBER(F, Number) \ - GLOBALOBJECT_BUILTIN_OBJECT(F, Object) \ - GLOBALOBJECT_BUILTIN_OTHERS(F, Others) \ - GLOBALOBJECT_BUILTIN_PROMISE(F, Promise) \ - GLOBALOBJECT_BUILTIN_PROXY(F, Proxy) \ - GLOBALOBJECT_BUILTIN_REFLECT(F, Reflect) \ - GLOBALOBJECT_BUILTIN_REGEXP(F, RegExp) \ - GLOBALOBJECT_BUILTIN_SET(F, Set) \ - GLOBALOBJECT_BUILTIN_SHAREDARRAYBUFFER(F, SharedArrayBuffer) \ - GLOBALOBJECT_BUILTIN_STRING(F, String) \ - GLOBALOBJECT_BUILTIN_SYMBOL(F, Symbol) \ - GLOBALOBJECT_BUILTIN_BIGINT(F, BigInt) \ - GLOBALOBJECT_BUILTIN_TYPEDARRAY(F, TypedArray) \ - GLOBALOBJECT_BUILTIN_WEAKMAP(F, WeakMap) \ - GLOBALOBJECT_BUILTIN_WEAKSET(F, WeakSet) \ - GLOBALOBJECT_BUILTIN_WEAKREF(F, WeakRef) \ - GLOBALOBJECT_BUILTIN_FINALIZATIONREGISTRY(F, FinalizationRegistry) \ - GLOBALOBJECT_BUILTIN_WASM(F, WebAssembly) +#define GLOBALOBJECT_BUILTIN_OBJECT_LIST(F, ARG) \ + F(ARRAYBUFFER, ArrayBuffer, ARG) \ + F(ARRAY, Array, ARG) \ + F(ASYNCFROMSYNCITERATOR, AsyncFromSyncIterator, ARG) \ + F(ASYNCFUNCTION, AsyncFunction, ARG) \ + F(ASYNCGENERATOR, AsyncGenerator, ARG) \ + F(ATOMICS, Atomics, ARG) \ + F(BOOLEAN, Boolean, ARG) \ + F(DATAVIEW, DataView, ARG) \ + F(DATE, Date, ARG) \ + F(ERROR, Error, ARG) \ + F(FUNCTION, Function, ARG) \ + F(GENERATOR, Generator, ARG) \ + F(INTL, Intl, ARG) \ + F(JSON, JSON, ARG) \ + F(MAP, Map, ARG) \ + F(MATH, Math, ARG) \ + F(NUMBER, Number, ARG) \ + F(OBJECT, Object, ARG) \ + F(OTHERS, Others, ARG) \ + F(PROMISE, Promise, ARG) \ + F(PROXY, Proxy, ARG) \ + F(REFLECT, Reflect, ARG) \ + F(REGEXP, RegExp, ARG) \ + F(SET, Set, ARG) \ + F(SHAREDARRAYBUFFER, SharedArrayBuffer, ARG) \ + F(STRING, String, ARG) \ + F(SYMBOL, Symbol, ARG) \ + F(BIGINT, BigInt, ARG) \ + F(TYPEDARRAY, TypedArray, ARG) \ + F(WEAKMAP, WeakMap, ARG) \ + F(WEAKSET, WeakSet, ARG) \ + F(WEAKREF, WeakRef, ARG) \ + F(FINALIZATIONREGISTRY, FinalizationRegistry, ARG) \ + F(WASM, WebAssembly, ARG) + + +#define DECLARE_BUILTIN_ALL_LIST(OBJNAME, objName, ARG) \ + GLOBALOBJECT_BUILTIN_##OBJNAME(ARG, objName) + +#define GLOBALOBJECT_BUILTIN_ALL_LIST(F) \ + GLOBALOBJECT_BUILTIN_OBJECT_LIST(DECLARE_BUILTIN_ALL_LIST, F) Value builtinSpeciesGetter(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget); class GlobalObject : public Object { public: - friend class ByteCodeInterpreter; friend class GlobalEnvironmentRecord; - friend class IdentifierNode; explicit GlobalObject(ExecutionState& state); @@ -290,22 +294,6 @@ public: return true; } - void installBuiltins(ExecutionState& state); - - Value eval(ExecutionState& state, const Value& arg); - // we get isInWithOperation as parameter because this affects bytecode - Value evalLocal(ExecutionState& state, const Value& arg, Value thisValue, InterpretedCodeBlock* parentCodeBlock, bool inWithOperation); - -#define DECLARE_BUILTIN_FUNC(builtin, TYPE, NAME) \ - TYPE* builtin() \ - { \ - ASSERT(!!m_##builtin); \ - return m_##builtin; \ - } - - GLOBALOBJECT_BUILTIN_LIST(DECLARE_BUILTIN_FUNC) -#undef DECLARE_BUILTIN_FUNC - virtual bool isInlineCacheable() override { return false; @@ -314,6 +302,31 @@ public: virtual ObjectHasPropertyResult hasProperty(ExecutionState& state, const ObjectPropertyName& P) override; virtual ObjectGetResult getOwnProperty(ExecutionState& state, const ObjectPropertyName& P) override; + /* + Global builtin property getter method + If builtin property is not yet installed (m_##builtin is null), call install#objName method to install it + Installation is executed only once for each builtin object + */ +#define DECLARE_BUILTIN_GETTER_FUNC(builtin, TYPE, objName) \ + TYPE* builtin() \ + { \ + if (UNLIKELY(!m_##builtin)) { \ + ExecutionState tempState(m_context); \ + install##objName(tempState); \ + } \ + ASSERT(!!m_##builtin); \ + return m_##builtin; \ + } + + GLOBALOBJECT_BUILTIN_ALL_LIST(DECLARE_BUILTIN_GETTER_FUNC) +#undef DECLARE_BUILTIN_GETTER_FUNC + + void initializeBuiltins(ExecutionState& state); + + Value eval(ExecutionState& state, const Value& arg); + // we get isInWithOperation as parameter because this affects bytecode + Value evalLocal(ExecutionState& state, const Value& arg, Value thisValue, InterpretedCodeBlock* parentCodeBlock, bool inWithOperation); + void* operator new(size_t size) { return GC_MALLOC(size); @@ -323,56 +336,21 @@ public: private: Context* m_context; -#define DECLARE_BUILTIN_VALUE(builtin, TYPE, NAME) \ +#define DECLARE_BUILTIN_MEMBER_VALUE(builtin, TYPE, objName) \ TYPE* m_##builtin; - GLOBALOBJECT_BUILTIN_LIST(DECLARE_BUILTIN_VALUE) -#undef DECLARE_BUILTIN_VALUE - - void installFunction(ExecutionState& state); - void installObject(ExecutionState& state); - void installError(ExecutionState& state); - void installSymbol(ExecutionState& state); - void installBigInt(ExecutionState& state); - void installString(ExecutionState& state); - void installNumber(ExecutionState& state); - void installBoolean(ExecutionState& state); - void installArray(ExecutionState& state); - void installMath(ExecutionState& state); - void installDate(ExecutionState& state); - void installRegExp(ExecutionState& state); - void installJSON(ExecutionState& state); -#if defined(ENABLE_ICU) && defined(ENABLE_INTL) - void installIntl(ExecutionState& state); -#endif - void installPromise(ExecutionState& state); - void installProxy(ExecutionState& state); - void installReflect(ExecutionState& state); - void installArrayBuffer(ExecutionState& state); - void installDataView(ExecutionState& state); - void installTypedArray(ExecutionState& state); + GLOBALOBJECT_BUILTIN_ALL_LIST(DECLARE_BUILTIN_MEMBER_VALUE) +#undef DECLARE_BUILTIN_MEMBER_VALUE + +#define DECLARE_BUILTIN_MEMBER_FUNC(OBJNAME, objName, ARG) \ + void initialize##objName(ExecutionState& state); \ + void install##objName(ExecutionState& state); + + GLOBALOBJECT_BUILTIN_OBJECT_LIST(DECLARE_BUILTIN_MEMBER_FUNC, ) +#undef DECLARE_BUILTIN_MEMBER_FUNC + template FunctionObject* installTypedArray(ExecutionState& state, AtomicString taName, Object** proto, FunctionObject* typedArrayFunction); - void installIterator(ExecutionState& state); - void installMap(ExecutionState& state); - void installSet(ExecutionState& state); - void installWeakMap(ExecutionState& state); - void installWeakRef(ExecutionState& state); - void installWeakSet(ExecutionState& state); - void installFinalizationRegistry(ExecutionState& state); - void installGenerator(ExecutionState& state); - void installAsyncFunction(ExecutionState& state); - void installAsyncIterator(ExecutionState& state); - void installAsyncFromSyncIterator(ExecutionState& state); - void installAsyncGeneratorFunction(ExecutionState& state); -#if defined(ENABLE_THREADING) - void installAtomics(ExecutionState& state); - void installSharedArrayBuffer(ExecutionState& state); -#endif -#if defined(ENABLE_WASM) - void installWASM(ExecutionState& state); -#endif - void installOthers(ExecutionState& state); }; } // namespace Escargot diff --git a/lwnode/code/escargotshim/deps/escargot/src/runtime/NumberObject.cpp b/lwnode/code/escargotshim/deps/escargot/src/runtime/NumberObject.cpp index b6e715d..f0e1dfa 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/runtime/NumberObject.cpp +++ b/lwnode/code/escargotshim/deps/escargot/src/runtime/NumberObject.cpp @@ -469,7 +469,7 @@ char* NumberObject::toStringWithRadix(ExecutionState& state, RadixBuffer& buffer // examine the remainder to determine whether we should be considering rounding // up or down. If remainder is precisely 0.5 rounding is to even. int dComparePoint5 = fraction.comparePoint5(); - if (dComparePoint5 > 0 || (!dComparePoint5 && (radix & 1 ? isOddInOddRadix : digit & 1))) { + if (dComparePoint5 > 0 || (!dComparePoint5 && ((radix & 1) ? isOddInOddRadix : (digit & 1)))) { // Check for rounding up; are we closer to the value we'd round off to than // the next IEEE value would be? if (fraction.sumGreaterThanOne(halfDeltaNext)) { @@ -503,7 +503,7 @@ char* NumberObject::toStringWithRadix(ExecutionState& state, RadixBuffer& buffer while (true) { int dComparePoint5 = fraction.comparePoint5(); - if (dComparePoint5 > 0 || (!dComparePoint5 && (radix & 1 ? isOddInOddRadix : digit & 1))) { + if (dComparePoint5 > 0 || (!dComparePoint5 && ((radix & 1) ? isOddInOddRadix : (digit & 1)))) { if (fraction.sumGreaterThanOne(halfDelta)) { needsRoundingUp = true; break; diff --git a/lwnode/code/escargotshim/deps/escargot/src/runtime/Object.cpp b/lwnode/code/escargotshim/deps/escargot/src/runtime/Object.cpp index 4f81a1a..56ce9fc 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/runtime/Object.cpp +++ b/lwnode/code/escargotshim/deps/escargot/src/runtime/Object.cpp @@ -1408,48 +1408,61 @@ ArrayObject* Object::createArrayFromList(ExecutionState& state, const ValueVecto ValueVector Object::createListFromArrayLike(ExecutionState& state, Value obj, uint8_t elementTypes) { - // https://www.ecma-international.org/ecma-262/6.0/#sec-createlistfromarraylike + // https://tc39.es/ecma262/#sec-createlistfromarraylike auto strings = &state.context()->staticStrings(); - // 1. ReturnIfAbrupt(obj). - // 2. If elementTypes was not passed, let elementTypes be (Undefined, Null, Boolean, String, Symbol, Number, Object). - - // 3. If Type(obj) is not Object, throw a TypeError exception. + // If elementTypes is not present, set elementTypes to « Undefined, Null, Boolean, String, Symbol, Number, BigInt, Object ». + // If Type(obj) is not Object, throw a TypeError exception. if (!obj.isObject()) { - ErrorObject::throwBuiltinError(state, ErrorObject::TypeError, strings->object.string(), false, String::emptyString, "%s: obj is not Object"); + ErrorObject::throwBuiltinError(state, ErrorObject::TypeError, ErrorObject::Messages::GlobalObject_FirstArgumentNotObject); } - // 4. Let len be ToLength(Get(obj, "length")). - // 5. ReturnIfAbrupt(len). + // Let len be ? LengthOfArrayLike(obj). Object* o = obj.asObject(); auto len = o->length(state); - // Honorate "length" property: If length>2^32-1, throw a RangeError exception. - if (len > ((1LL << 32LL) - 1LL)) { - ErrorObject::throwBuiltinError(state, ErrorObject::RangeError, ErrorObject::Messages::GlobalObject_InvalidArrayLength); - } - - // 6. Let list be an empty List. + // Let list be an empty List. + // Let index be 0. ValueVector list; - // 7. Let index be 0. uint64_t index = 0; - //8. Repeat while index < len + bool allTypes = (elementTypes == static_cast(ElementTypes::ALL)); + + // Repeat while index < len while (index < len) { - // b. Let next be Get(obj, indexName). - // c. ReturnIfAbrupt(next). + // Let next be Get(obj, indexName). Value next = o->getIndexedProperty(state, Value(index)).value(state, o); - // d. If Type(next) is not an element of elementTypes, throw a TypeError exception. - if (!(((elementTypes & (uint8_t)ElementTypes::Undefined) && next.isUndefined()) || ((elementTypes & (uint8_t)ElementTypes::Null) && next.isNull()) || ((elementTypes & (uint8_t)ElementTypes::Boolean) && next.isBoolean()) || ((elementTypes & (uint8_t)ElementTypes::String) && next.isString()) || ((elementTypes & (uint8_t)ElementTypes::Symbol) && next.isSymbol()) || ((elementTypes & (uint8_t)ElementTypes::Number) && next.isNumber()) || ((elementTypes & (uint8_t)ElementTypes::Object) && next.isObject()))) { + // If Type(next) is not an element of elementTypes, throw a TypeError exception. + bool validType = false; + if (next.isUndefined()) { + validType = allTypes || (elementTypes & static_cast(ElementTypes::Undefined)); + } else if (next.isNull()) { + validType = allTypes || (elementTypes & static_cast(ElementTypes::Null)); + } else if (next.isBoolean()) { + validType = allTypes || (elementTypes & static_cast(ElementTypes::Boolean)); + } else if (next.isString()) { + validType = allTypes || (elementTypes & static_cast(ElementTypes::String)); + } else if (next.isSymbol()) { + validType = allTypes || (elementTypes & static_cast(ElementTypes::Symbol)); + } else if (next.isNumber()) { + validType = allTypes || (elementTypes & static_cast(ElementTypes::Number)); + } else if (next.isBigInt()) { + validType = allTypes || (elementTypes & static_cast(ElementTypes::BigInt)); + } else if (next.isObject()) { + validType = allTypes || (elementTypes & static_cast(ElementTypes::Object)); + } + + if (UNLIKELY(!validType)) { ErrorObject::throwBuiltinError(state, ErrorObject::TypeError, strings->object.string(), false, String::emptyString, "%s: Type(next) is not an element of elementTypes"); } - // e. Append next as the last element of list. + + // Append next as the last element of list. list.pushBack(next); - // f. Set index to index + 1. + // Set index to index + 1. index++; } - // 9. Return list. + // Return list. return list; } @@ -1466,6 +1479,28 @@ void Object::markAsNonInlineCachable() ensureRareData()->m_isInlineCacheable = false; } +void Object::redefineOwnProperty(ExecutionState& state, const ObjectPropertyName& P, const ObjectPropertyDescriptor& desc) +{ + ASSERT(!P.isIndexString()); + ASSERT(desc.isDataProperty()); + ASSERT(desc.isWritable()); + ASSERT(desc.isConfigurable()); + + ObjectStructurePropertyName propertyName = P.toObjectStructurePropertyName(state); + auto findResult = m_structure->findProperty(propertyName); + ASSERT(findResult.first != SIZE_MAX); + + size_t idx = findResult.first; + const ObjectStructureItem* item = findResult.second.value(); + auto current = item->m_descriptor; + ASSERT(current.isDataProperty()); + ASSERT(current.isWritable()); + ASSERT(current.isConfigurable()); + + m_structure = m_structure->replacePropertyDescriptor(idx, desc.toObjectStructurePropertyDescriptor()); + m_values[idx] = desc.value(); +} + uint64_t Object::length(ExecutionState& state) { // ToLength(Get(obj, "length")) diff --git a/lwnode/code/escargotshim/deps/escargot/src/runtime/Object.h b/lwnode/code/escargotshim/deps/escargot/src/runtime/Object.h index f1bcf7c..7cdd8b0 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/runtime/Object.h +++ b/lwnode/code/escargotshim/deps/escargot/src/runtime/Object.h @@ -757,8 +757,9 @@ enum class ElementTypes : uint8_t { String = 1 << 3, Symbol = 1 << 4, Number = 1 << 5, - Object = 1 << 6, - ALL = Undefined | Null | Boolean | String | Symbol | Number | Object + BigInt = 1 << 6, + Object = 1 << 7, + ALL = Undefined | Null | Boolean | String | Symbol | Number | BigInt | Object }; class Object : public PointerValue { @@ -908,13 +909,6 @@ public: } } - void defineOwnPropertyThrowsExceptionWhenStrictMode(ExecutionState& state, const ObjectPropertyName& P, const ObjectPropertyDescriptor& desc) - { - if (!defineOwnProperty(state, P, desc) && state.inStrictMode()) { - throwCannotDefineError(state, P.toObjectStructurePropertyName(state)); - } - } - void deleteOwnPropertyThrowsException(ExecutionState& state, const ObjectPropertyName& P) { if (!deleteOwnProperty(state, P)) { @@ -1087,7 +1081,7 @@ public: static void throwCannotDeleteError(ExecutionState& state, const ObjectStructurePropertyName& P); static ArrayObject* createArrayFromList(ExecutionState& state, const uint64_t& size, const Value* buffer); static ArrayObject* createArrayFromList(ExecutionState& state, const ValueVector& elements); - static ValueVector createListFromArrayLike(ExecutionState& state, Value obj, uint8_t types = (uint8_t)ElementTypes::ALL); + static ValueVector createListFromArrayLike(ExecutionState& state, Value obj, uint8_t types = static_cast(ElementTypes::ALL)); static ValueVectorWithInlineStorage enumerableOwnProperties(ExecutionState& state, Object* object, EnumerableOwnPropertiesType kind); // this function differ with defineOwnProperty. @@ -1246,6 +1240,9 @@ protected: void deleteOwnProperty(ExecutionState& state, size_t idx); void markAsNonInlineCachable(); + + // redefine function used only for builtin installation + void redefineOwnProperty(ExecutionState& state, const ObjectPropertyName& P, const ObjectPropertyDescriptor& desc); }; } // namespace Escargot diff --git a/lwnode/code/escargotshim/deps/escargot/src/runtime/Platform.h b/lwnode/code/escargotshim/deps/escargot/src/runtime/Platform.h index 5c2888e..98fc653 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/runtime/Platform.h +++ b/lwnode/code/escargotshim/deps/escargot/src/runtime/Platform.h @@ -48,6 +48,8 @@ public: virtual void didLoadModule(Context* relatedContext, Optional whereRequestFrom, Script* loadedModule) = 0; virtual void hostImportModuleDynamically(Context* relatedContext, Script* referrer, String* src, PromiseObject* promise) = 0; + virtual bool canBlockExecution(Context* relatedContext) = 0; + // ThreadLocal custom data (g_customData) virtual void* allocateThreadLocalCustomData() = 0; virtual void deallocateThreadLocalCustomData() = 0; diff --git a/lwnode/code/escargotshim/deps/escargot/src/runtime/PointerValue.h b/lwnode/code/escargotshim/deps/escargot/src/runtime/PointerValue.h index dc0c61f..7ca0c53 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/runtime/PointerValue.h +++ b/lwnode/code/escargotshim/deps/escargot/src/runtime/PointerValue.h @@ -75,6 +75,7 @@ class SharedArrayBufferObject; #if defined(ENABLE_INTL) class IntlLocaleObject; class IntlPluralRulesObject; +class IntlDateTimeFormatObject; class IntlRelativeTimeFormatObject; #endif #if defined(ENABLE_WASM) @@ -431,6 +432,11 @@ public: return false; } + virtual bool isIntlDateTimeFormatObject() const + { + return false; + } + virtual bool isIntlRelativeTimeFormatObject() const { return false; @@ -788,6 +794,12 @@ public: return (IntlPluralRulesObject*)this; } + IntlDateTimeFormatObject* asIntlDateTimeFormatObject() + { + ASSERT(isIntlDateTimeFormatObject()); + return (IntlDateTimeFormatObject*)this; + } + IntlRelativeTimeFormatObject* asIntlRelativeTimeFormatObject() { ASSERT(isIntlRelativeTimeFormatObject()); diff --git a/lwnode/code/escargotshim/deps/escargot/src/runtime/ProxyObject.cpp b/lwnode/code/escargotshim/deps/escargot/src/runtime/ProxyObject.cpp index 9b7d518..f8ee769 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/runtime/ProxyObject.cpp +++ b/lwnode/code/escargotshim/deps/escargot/src/runtime/ProxyObject.cpp @@ -503,7 +503,7 @@ Object::OwnPropertyKeyVector ProxyObject::ownPropertyKeys(ExecutionState& state) Value trapResultArray; Value arguments[] = { target }; trapResultArray = Object::call(state, trap, handler, 1, arguments); - auto trapResult = Object::createListFromArrayLike(state, trapResultArray, ((uint8_t)ElementTypes::String | (uint8_t)ElementTypes::Symbol)); + auto trapResult = Object::createListFromArrayLike(state, trapResultArray, (static_cast(ElementTypes::String) | static_cast(ElementTypes::Symbol))); // If trapResult contains any duplicate entries, throw a TypeError exception for (size_t i = 0; i < trapResult.size(); i++) { diff --git a/lwnode/code/escargotshim/deps/escargot/src/runtime/ScriptArrowFunctionObject.cpp b/lwnode/code/escargotshim/deps/escargot/src/runtime/ScriptArrowFunctionObject.cpp index 26acbdb..93bfe03 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/runtime/ScriptArrowFunctionObject.cpp +++ b/lwnode/code/escargotshim/deps/escargot/src/runtime/ScriptArrowFunctionObject.cpp @@ -39,7 +39,9 @@ Value ScriptArrowFunctionObject::call(ExecutionState& state, const Value& thisVa Value ScriptArrowFunctionObject::construct(ExecutionState& state, const size_t argc, Value* argv, Object* newTarget) { - ErrorObject::throwBuiltinError(state, ErrorObject::TypeError, "Arrow function cannot be invoked with 'new'"); + ExecutionState newState(m_codeBlock->context(), &state, + static_cast(nullptr), argc, argv, m_codeBlock->asInterpretedCodeBlock()->isStrict()); + ErrorObject::throwBuiltinError(newState, ErrorObject::TypeError, "Arrow function cannot be invoked with 'new'"); ASSERT_NOT_REACHED(); return Value(); } diff --git a/lwnode/code/escargotshim/deps/escargot/src/runtime/ScriptAsyncFunctionObject.cpp b/lwnode/code/escargotshim/deps/escargot/src/runtime/ScriptAsyncFunctionObject.cpp index 74fd3f7..e0bceb8 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/runtime/ScriptAsyncFunctionObject.cpp +++ b/lwnode/code/escargotshim/deps/escargot/src/runtime/ScriptAsyncFunctionObject.cpp @@ -77,7 +77,9 @@ Value ScriptAsyncFunctionObject::call(ExecutionState& state, const Value& thisVa Value ScriptAsyncFunctionObject::construct(ExecutionState& state, const size_t argc, Value* argv, Object* newTarget) { - ErrorObject::throwBuiltinError(state, ErrorObject::TypeError, "Async function cannot be invoked with 'new'"); + ExecutionState newState(m_codeBlock->context(), &state, + static_cast(nullptr), argc, argv, m_codeBlock->asInterpretedCodeBlock()->isStrict()); + ErrorObject::throwBuiltinError(newState, ErrorObject::TypeError, "Async function cannot be invoked with 'new'"); ASSERT_NOT_REACHED(); return Value(); } diff --git a/lwnode/code/escargotshim/deps/escargot/src/runtime/ScriptAsyncGeneratorFunctionObject.cpp b/lwnode/code/escargotshim/deps/escargot/src/runtime/ScriptAsyncGeneratorFunctionObject.cpp index e96f41a..596a288 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/runtime/ScriptAsyncGeneratorFunctionObject.cpp +++ b/lwnode/code/escargotshim/deps/escargot/src/runtime/ScriptAsyncGeneratorFunctionObject.cpp @@ -75,7 +75,9 @@ Value ScriptAsyncGeneratorFunctionObject::call(ExecutionState& state, const Valu Value ScriptAsyncGeneratorFunctionObject::construct(ExecutionState& state, const size_t argc, Value* argv, Object* newTarget) { - ErrorObject::throwBuiltinError(state, ErrorObject::TypeError, "AsyncGenerator cannot be invoked with 'new'"); + ExecutionState newState(m_codeBlock->context(), &state, + static_cast(nullptr), argc, argv, m_codeBlock->asInterpretedCodeBlock()->isStrict()); + ErrorObject::throwBuiltinError(newState, ErrorObject::TypeError, "AsyncGenerator cannot be invoked with 'new'"); ASSERT_NOT_REACHED(); return Value(); } diff --git a/lwnode/code/escargotshim/deps/escargot/src/runtime/ScriptClassConstructorFunctionObject.cpp b/lwnode/code/escargotshim/deps/escargot/src/runtime/ScriptClassConstructorFunctionObject.cpp index 66eda44..455ca1c 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/runtime/ScriptClassConstructorFunctionObject.cpp +++ b/lwnode/code/escargotshim/deps/escargot/src/runtime/ScriptClassConstructorFunctionObject.cpp @@ -60,7 +60,8 @@ ScriptClassConstructorFunctionObject::ScriptClassConstructorFunctionObject(Execu Value ScriptClassConstructorFunctionObject::call(ExecutionState& state, const Value& thisValue, const size_t argc, Value* argv) { - ErrorObject::throwBuiltinError(state, ErrorObject::TypeError, "Class constructor cannot be invoked without 'new'"); + ExecutionState newState(m_codeBlock->context(), &state, static_cast(nullptr), argc, argv, m_codeBlock->asInterpretedCodeBlock()->isStrict()); + ErrorObject::throwBuiltinError(newState, ErrorObject::TypeError, "Class constructor cannot be invoked without 'new'"); return Value(); } diff --git a/lwnode/code/escargotshim/deps/escargot/src/runtime/ScriptGeneratorFunctionObject.cpp b/lwnode/code/escargotshim/deps/escargot/src/runtime/ScriptGeneratorFunctionObject.cpp index 0f9300e..2ac6c13 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/runtime/ScriptGeneratorFunctionObject.cpp +++ b/lwnode/code/escargotshim/deps/escargot/src/runtime/ScriptGeneratorFunctionObject.cpp @@ -75,7 +75,9 @@ Value ScriptGeneratorFunctionObject::call(ExecutionState& state, const Value& th Value ScriptGeneratorFunctionObject::construct(ExecutionState& state, const size_t argc, Value* argv, Object* newTarget) { - ErrorObject::throwBuiltinError(state, ErrorObject::TypeError, "Generator cannot be invoked with 'new'"); + ExecutionState newState(m_codeBlock->context(), &state, + static_cast(nullptr), argc, argv, m_codeBlock->asInterpretedCodeBlock()->isStrict()); + ErrorObject::throwBuiltinError(newState, ErrorObject::TypeError, "Generator cannot be invoked with 'new'"); ASSERT_NOT_REACHED(); return Value(); } diff --git a/lwnode/code/escargotshim/deps/escargot/src/runtime/ScriptVirtualArrowFunctionObject.cpp b/lwnode/code/escargotshim/deps/escargot/src/runtime/ScriptVirtualArrowFunctionObject.cpp index e08a120..7332f69 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/runtime/ScriptVirtualArrowFunctionObject.cpp +++ b/lwnode/code/escargotshim/deps/escargot/src/runtime/ScriptVirtualArrowFunctionObject.cpp @@ -51,14 +51,18 @@ Value ScriptVirtualArrowFunctionObject::call(ExecutionState& state, const Value& Value ScriptVirtualArrowFunctionObject::call(ExecutionState& state, const Value& thisValue, const size_t argc, Value* argv) { - ErrorObject::throwBuiltinError(state, ErrorObject::TypeError, "This function cannot be invoked"); + ExecutionState newState(m_codeBlock->context(), &state, + static_cast(nullptr), argc, argv, m_codeBlock->asInterpretedCodeBlock()->isStrict()); + ErrorObject::throwBuiltinError(newState, ErrorObject::TypeError, "This function cannot be invoked"); ASSERT_NOT_REACHED(); return Value(); } Value ScriptVirtualArrowFunctionObject::construct(ExecutionState& state, const size_t argc, Value* argv, Object* newTarget) { - ErrorObject::throwBuiltinError(state, ErrorObject::TypeError, "This function cannot be invoked"); + ExecutionState newState(m_codeBlock->context(), &state, + static_cast(nullptr), argc, argv, m_codeBlock->asInterpretedCodeBlock()->isStrict()); + ErrorObject::throwBuiltinError(newState, ErrorObject::TypeError, "This function cannot be invoked"); ASSERT_NOT_REACHED(); return Value(); } diff --git a/lwnode/code/escargotshim/deps/escargot/src/runtime/StaticStrings.cpp b/lwnode/code/escargotshim/deps/escargot/src/runtime/StaticStrings.cpp index e2f86a5..e1c4e92 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/runtime/StaticStrings.cpp +++ b/lwnode/code/escargotshim/deps/escargot/src/runtime/StaticStrings.cpp @@ -154,6 +154,7 @@ void StaticStrings::initStaticStrings() #define DECLARE_LAZY_STATIC_STRING(Name, unused) m_lazy##Name = AtomicString(); FOR_EACH_LAZY_STATIC_STRING(DECLARE_LAZY_STATIC_STRING); FOR_EACH_LAZY_INTL_STATIC_STRING(DECLARE_LAZY_STATIC_STRING); + FOR_EACH_LAZY_THREADING_STATIC_STRING(DECLARE_LAZY_STATIC_STRING); #undef DECLARE_LAZY_STATIC_STRING } @@ -167,6 +168,7 @@ void StaticStrings::initStaticStrings() } FOR_EACH_LAZY_STATIC_STRING(DECLARE_LAZY_STATIC_STRING); FOR_EACH_LAZY_INTL_STATIC_STRING(DECLARE_LAZY_STATIC_STRING); +FOR_EACH_LAZY_THREADING_STATIC_STRING(DECLARE_LAZY_STATIC_STRING); #undef DECLARE_LAZY_STATIC_STRING ::Escargot::String* StaticStrings::dtoa(double d) const diff --git a/lwnode/code/escargotshim/deps/escargot/src/runtime/StaticStrings.h b/lwnode/code/escargotshim/deps/escargot/src/runtime/StaticStrings.h index b77e02e..b677135 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/runtime/StaticStrings.h +++ b/lwnode/code/escargotshim/deps/escargot/src/runtime/StaticStrings.h @@ -161,6 +161,7 @@ namespace Escargot { F(callee) \ F(caller) \ F(caseFirst) \ + F(cause) \ F(cbrt) \ F(ceil) \ F(charAt) \ @@ -208,6 +209,8 @@ namespace Escargot { F(finally) \ F(find) \ F(findIndex) \ + F(findLast) \ + F(findLastIndex) \ F(fixed) \ F(flags) \ F(flat) \ @@ -267,6 +270,7 @@ namespace Escargot { F(groups) \ F(has) \ F(hasInstance) \ + F(hasOwn) \ F(hasOwnProperty) \ F(hourCycle) \ F(hypot) \ @@ -671,103 +675,117 @@ namespace Escargot { F(URL, "url") #if defined(ENABLE_INTL) -#define FOR_EACH_LAZY_INTL_STATIC_STRING(F) \ - F(Accent, "accent") \ - F(Accounting, "accounting") \ - F(Always, "always") \ - F(Any, "any") \ - F(Auto, "auto") \ - F(Base, "base") \ - F(Basic, "basic") \ - F(BestFit, "best fit") \ - F(Cardinal, "cardinal") \ - F(Case, "case") \ - F(Code, "code") \ - F(Compact, "compact") \ - F(CompactDisplay, "compactDisplay") \ - F(CompareFunction, "compareFunction") \ - F(Currency, "currency") \ - F(CurrencyDisplay, "currencyDisplay") \ - F(CurrencySign, "currencySign") \ - F(DashU, "-u") \ - F(DataLocale, "dataLocale") \ - F(Date, "date") \ - F(Day, "day") \ - F(DayPeriod, "dayPeriod") \ - F(Decimal, "decimal") \ - F(Engineering, "engineering") \ - F(Era, "era") \ - F(ExceptZero, "exceptZero") \ - F(ExponentInteger, "exponentInteger") \ - F(ExponentMinusSign, "exponentMinusSign") \ - F(ExponentSeparator, "exponentSeparator") \ - F(FormatMatcher, "formatMatcher") \ - F(Fraction, "fraction") \ - F(Group, "group") \ - F(H11, "h11") \ - F(H12, "h12") \ - F(H23, "h23") \ - F(H24, "h24") \ - F(Hour, "hour") \ - F(Hour12, "hour12") \ - F(IgnorePunctuation, "ignorePunctuation") \ - F(InitializedCollator, "initializedCollator") \ - F(InitializedDateTimeFormat, "initializedDateTimeFormat") \ - F(InitializedIntlObject, "initializedIntlObject") \ - F(InitializedNumberFormat, "initializedNumberFormat") \ - F(Integer, "integer") \ - F(Kf, "kf") \ - F(Kn, "kn") \ - F(Literal, "literal") \ - F(LocaleMatcher, "localeMatcher") \ - F(Long, "long") \ - F(Lookup, "lookup") \ - F(Lower, "lower") \ - F(MaximumFractionDigits, "maximumFractionDigits") \ - F(MaximumSignificantDigits, "maximumSignificantDigits") \ - F(MinimumFractionDigits, "minimumFractionDigits") \ - F(MinimumIntegerDigits, "minimumIntegerDigits") \ - F(MinimumSignificantDigits, "minimumSignificantDigits") \ - F(MinusSign, "minusSign") \ - F(Minute, "minute") \ - F(Month, "month") \ - F(Narrow, "narrow") \ - F(NarrowSymbol, "narrowSymbol") \ - F(Never, "never") \ - F(Notation, "notation") \ - F(Ordinal, "ordinal") \ - F(Percent, "percent") \ - F(PercentSign, "percentSign") \ - F(PlusSign, "plusSign") \ - F(Quarter, "quarter") \ - F(Scientific, "scientific") \ - F(Second, "second") \ - F(Sensitivity, "sensitivity") \ - F(Short, "short") \ - F(SignDisplay, "signDisplay") \ - F(SmallLetterInfinity, "infinity") \ - F(SmallLetterLocale, "locale") \ - F(SmallLetterNaN, "nan") \ - F(Standard, "standard") \ - F(Style, "style") \ - F(Time, "time") \ - F(TimeZone, "timeZone") \ - F(TimeZoneName, "timeZoneName") \ - F(TwoDigit, "2-digit") \ - F(Type, "type") \ - F(Unit, "unit") \ - F(UnitDisplay, "unitDisplay") \ - F(Upper, "upper") \ - F(Usage, "usage") \ - F(UseGrouping, "useGrouping") \ - F(Variant, "variant") \ - F(Week, "week") \ - F(Weekday, "weekday") \ +#define FOR_EACH_LAZY_INTL_STATIC_STRING(F) \ + F(Accent, "accent") \ + F(Accounting, "accounting") \ + F(Always, "always") \ + F(Any, "any") \ + F(Auto, "auto") \ + F(Base, "base") \ + F(Basic, "basic") \ + F(BestFit, "best fit") \ + F(Cardinal, "cardinal") \ + F(Case, "case") \ + F(Code, "code") \ + F(Compact, "compact") \ + F(CompactDisplay, "compactDisplay") \ + F(CompareFunction, "compareFunction") \ + F(Currency, "currency") \ + F(CurrencyDisplay, "currencyDisplay") \ + F(CurrencySign, "currencySign") \ + F(DashU, "-u") \ + F(DataLocale, "dataLocale") \ + F(Date, "date") \ + F(DateStyle, "dateStyle") \ + F(Day, "day") \ + F(DayPeriod, "dayPeriod") \ + F(Decimal, "decimal") \ + F(Engineering, "engineering") \ + F(Era, "era") \ + F(ExceptZero, "exceptZero") \ + F(ExponentInteger, "exponentInteger") \ + F(ExponentMinusSign, "exponentMinusSign") \ + F(ExponentSeparator, "exponentSeparator") \ + F(FormatMatcher, "formatMatcher") \ + F(Fraction, "fraction") \ + F(FractionalSecond, "fractionalSecond") \ + F(FractionalSecondDigits, "fractionalSecondDigits") \ + F(Full, "full") \ + F(Group, "group") \ + F(H11, "h11") \ + F(H12, "h12") \ + F(H23, "h23") \ + F(H24, "h24") \ + F(Hour, "hour") \ + F(Hour12, "hour12") \ + F(IgnorePunctuation, "ignorePunctuation") \ + F(InitializedCollator, "initializedCollator") \ + F(InitializedIntlObject, "initializedIntlObject") \ + F(InitializedNumberFormat, "initializedNumberFormat") \ + F(Integer, "integer") \ + F(Kf, "kf") \ + F(Kn, "kn") \ + F(Literal, "literal") \ + F(LocaleMatcher, "localeMatcher") \ + F(Long, "long") \ + F(Lookup, "lookup") \ + F(Lower, "lower") \ + F(MaximumFractionDigits, "maximumFractionDigits") \ + F(MaximumSignificantDigits, "maximumSignificantDigits") \ + F(Medium, "medium") \ + F(MinimumFractionDigits, "minimumFractionDigits") \ + F(MinimumIntegerDigits, "minimumIntegerDigits") \ + F(MinimumSignificantDigits, "minimumSignificantDigits") \ + F(MinusSign, "minusSign") \ + F(Minute, "minute") \ + F(Month, "month") \ + F(Narrow, "narrow") \ + F(NarrowSymbol, "narrowSymbol") \ + F(Never, "never") \ + F(Notation, "notation") \ + F(Ordinal, "ordinal") \ + F(Percent, "percent") \ + F(PercentSign, "percentSign") \ + F(PlusSign, "plusSign") \ + F(Quarter, "quarter") \ + F(Scientific, "scientific") \ + F(Second, "second") \ + F(Sensitivity, "sensitivity") \ + F(Short, "short") \ + F(SignDisplay, "signDisplay") \ + F(SmallLetterInfinity, "infinity") \ + F(SmallLetterLocale, "locale") \ + F(SmallLetterNaN, "nan") \ + F(Standard, "standard") \ + F(Style, "style") \ + F(Time, "time") \ + F(TimeStyle, "timeStyle") \ + F(TimeZone, "timeZone") \ + F(TimeZoneName, "timeZoneName") \ + F(TwoDigit, "2-digit") \ + F(Type, "type") \ + F(Unit, "unit") \ + F(UnitDisplay, "unitDisplay") \ + F(Upper, "upper") \ + F(Usage, "usage") \ + F(UseGrouping, "useGrouping") \ + F(Variant, "variant") \ + F(Week, "week") \ + F(Weekday, "weekday") \ F(Year, "year") #else #define FOR_EACH_LAZY_INTL_STATIC_STRING(F) #endif +#if defined(ENABLE_THREADING) +#define FOR_EACH_LAZY_THREADING_STATIC_STRING(F) \ + F(NotEqual, "not-equal") \ + F(Ok, "ok") \ + F(TimedOut, "timed-out") +#else +#define FOR_EACH_LAZY_THREADING_STATIC_STRING(F) +#endif + class StaticStrings { public: StaticStrings(AtomicStringMap* atomicStringMap) @@ -890,6 +908,7 @@ public: #define DECLARE_LAZY_STATIC_STRING(Name, unused) AtomicString lazy##Name(); FOR_EACH_LAZY_STATIC_STRING(DECLARE_LAZY_STATIC_STRING); FOR_EACH_LAZY_INTL_STATIC_STRING(DECLARE_LAZY_STATIC_STRING); + FOR_EACH_LAZY_THREADING_STATIC_STRING(DECLARE_LAZY_STATIC_STRING); #undef DECLARE_LAZY_STATIC_STRING void initStaticStrings(); @@ -905,6 +924,7 @@ protected: #define DECLARE_LAZY_STATIC_STRING(Name, unused) AtomicString m_lazy##Name; FOR_EACH_LAZY_STATIC_STRING(DECLARE_LAZY_STATIC_STRING); FOR_EACH_LAZY_INTL_STATIC_STRING(DECLARE_LAZY_STATIC_STRING); + FOR_EACH_LAZY_THREADING_STATIC_STRING(DECLARE_LAZY_STATIC_STRING); #undef DECLARE_LAZY_STATIC_STRING }; } // namespace Escargot diff --git a/lwnode/code/escargotshim/deps/escargot/src/shell/Shell.cpp b/lwnode/code/escargotshim/deps/escargot/src/shell/Shell.cpp index f30fef0..2e9cf06 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/shell/Shell.cpp +++ b/lwnode/code/escargotshim/deps/escargot/src/shell/Shell.cpp @@ -540,6 +540,18 @@ static ValueRef* builtin262AgentSleep(ExecutionStateRef* state, ValueRef* thisVa class ShellPlatform : public PlatformRef { public: + bool m_canBlock; + + ShellPlatform() + : m_canBlock(true) + { + } + + void setCanBlock(bool b) + { + m_canBlock = b; + } + virtual void markJSJobEnqueued(ContextRef* relatedContext) override { // ignore. we always check pending job after eval script @@ -601,6 +613,11 @@ public: notifyHostImportModuleDynamicallyResult(relatedContext, referrer, src, promise, loadedModuleResult); } + virtual bool canBlockExecution(ContextRef* relatedContext) override + { + return m_canBlock; + } + virtual void* allocateThreadLocalCustomData() override { return new std::vector>>(); @@ -913,7 +930,8 @@ int main(int argc, char* argv[]) mallopt(M_MMAP_MAX, 1024 * 1024); #endif - Globals::initialize(new ShellPlatform()); + ShellPlatform* platform = new ShellPlatform(); + Globals::initialize(platform); Memory::setGCFrequency(24); @@ -940,6 +958,10 @@ int main(int argc, char* argv[]) seenModule = true; continue; } + if (strcmp(argv[i], "--canblock-is-false") == 0) { + platform->setCanBlock(false); + continue; + } if (strstr(argv[i], "--filename-as=") == argv[i]) { fileName = argv[i] + sizeof("--filename-as=") - 1; continue; diff --git a/lwnode/code/escargotshim/deps/escargot/src/wasm/GlobalObjectBuiltinWASM.cpp b/lwnode/code/escargotshim/deps/escargot/src/wasm/BuiltinWASM.cpp similarity index 96% rename from lwnode/code/escargotshim/deps/escargot/src/wasm/GlobalObjectBuiltinWASM.cpp rename to lwnode/code/escargotshim/deps/escargot/src/wasm/BuiltinWASM.cpp index ca87e12..5f3aa83 100644 --- a/lwnode/code/escargotshim/deps/escargot/src/wasm/GlobalObjectBuiltinWASM.cpp +++ b/lwnode/code/escargotshim/deps/escargot/src/wasm/BuiltinWASM.cpp @@ -919,35 +919,51 @@ static Value builtinWASMGlobalValueSetter(ExecutionState& state, Value thisValue } // WebAssemblly.Error -#define DEFINE_ERROR_CTOR(errorName, lowerCaseErrorName) \ - static Value builtin##errorName##ErrorConstructor(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) \ - { \ - if (!newTarget.hasValue()) { \ - newTarget = state.resolveCallee(); \ - } \ - Object* proto = Object::getPrototypeFromConstructor(state, newTarget.value(), [](ExecutionState& state, Context* constructorRealm) -> Object* { \ - return constructorRealm->globalObject()->lowerCaseErrorName##ErrorPrototype(); \ - }); \ - ErrorObject* obj = new errorName##ErrorObject(state, proto, String::emptyString); \ - Value message = argv[0]; \ - if (!message.isUndefined()) { \ - obj->defineOwnPropertyThrowsExceptionWhenStrictMode(state, state.context()->staticStrings().message, \ - ObjectPropertyDescriptor(message.toString(state), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectStructurePropertyDescriptor::ConfigurablePresent))); \ - } \ - return obj; \ +#define DEFINE_ERROR_CTOR(errorName, lowerCaseErrorName) \ + static Value builtin##errorName##ErrorConstructor(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) \ + { \ + if (!newTarget.hasValue()) { \ + newTarget = state.resolveCallee(); \ + } \ + Object* proto = Object::getPrototypeFromConstructor(state, newTarget.value(), [](ExecutionState& state, Context* constructorRealm) -> Object* { \ + return constructorRealm->globalObject()->lowerCaseErrorName##ErrorPrototype(); \ + }); \ + ErrorObject* obj = new errorName##ErrorObject(state, proto, String::emptyString); \ + Value message = argv[0]; \ + if (!message.isUndefined()) { \ + obj->defineOwnPropertyThrowsException(state, state.context()->staticStrings().message, \ + ObjectPropertyDescriptor(message.toString(state), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectStructurePropertyDescriptor::ConfigurablePresent))); \ + } \ + return obj; \ } DEFINE_ERROR_CTOR(WASMCompile, wasmCompile) DEFINE_ERROR_CTOR(WASMLink, wasmLink) DEFINE_ERROR_CTOR(WASMRuntime, wasmRuntime) -void GlobalObject::installWASM(ExecutionState& state) +void GlobalObject::initializeWebAssembly(ExecutionState& state) +{ + ObjectPropertyNativeGetterSetterData* nativeData = new ObjectPropertyNativeGetterSetterData(true, false, true, + [](ExecutionState& state, Object* self, const Value& receiver, const EncodedValue& privateDataFromObjectPrivateArea) -> Value { + ASSERT(self->isGlobalObject()); + return self->asGlobalObject()->wasm(); + }, + nullptr); + + defineNativeDataAccessorProperty(state, ObjectPropertyName(state.context()->staticStrings().WebAssembly), nativeData, Value(Value::EmptyValue)); +} + +void GlobalObject::installWebAssembly(ExecutionState& state) { // builtin Error should be installed ahead - ASSERT(!!this->error()); + if (!m_error) { + error(); + } + ASSERT(!!m_error); Object* wasm = new Object(state); wasm->setGlobalIntrinsicObject(state); + m_wasm = wasm; const StaticStrings* strings = &state.context()->staticStrings(); @@ -1124,8 +1140,22 @@ void GlobalObject::installWASM(ExecutionState& state) DEFINE_ERROR(wasmRuntime, WASMRuntime, Runtime) - defineOwnProperty(state, ObjectPropertyName(strings->WebAssembly), - ObjectPropertyDescriptor(wasm, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); + redefineOwnProperty(state, ObjectPropertyName(strings->WebAssembly), + ObjectPropertyDescriptor(wasm, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); +} +} // namespace Escargot + +#else + +#include "Escargot.h" +#include "runtime/GlobalObject.h" + +namespace Escargot { +class ExecutionState; + +void GlobalObject::initializeWebAssembly(ExecutionState& state) +{ + // dummy initialize function } } // namespace Escargot diff --git a/lwnode/code/escargotshim/deps/escargot/third_party/runtime_icu_binder/ICUPolyfill.h b/lwnode/code/escargotshim/deps/escargot/third_party/runtime_icu_binder/ICUPolyfill.h index 712ddf7..8af46bb 100644 --- a/lwnode/code/escargotshim/deps/escargot/third_party/runtime_icu_binder/ICUPolyfill.h +++ b/lwnode/code/escargotshim/deps/escargot/third_party/runtime_icu_binder/ICUPolyfill.h @@ -94,6 +94,7 @@ #define udat_formatForFields RuntimeICUBinder::ICU::instance().udat_formatForFields #define udat_close RuntimeICUBinder::ICU::instance().udat_close #define udat_getCalendar RuntimeICUBinder::ICU::instance().udat_getCalendar +#define udat_toPattern RuntimeICUBinder::ICU::instance().udat_toPattern #define uenum_count RuntimeICUBinder::ICU::instance().uenum_count #define uenum_unext RuntimeICUBinder::ICU::instance().uenum_unext @@ -120,6 +121,7 @@ #define udatpg_open RuntimeICUBinder::ICU::instance().udatpg_open #define udatpg_getBestPattern RuntimeICUBinder::ICU::instance().udatpg_getBestPattern #define udatpg_getBestPatternWithOptions RuntimeICUBinder::ICU::instance().udatpg_getBestPatternWithOptions +#define udatpg_getSkeleton RuntimeICUBinder::ICU::instance().udatpg_getSkeleton #define ubrk_open RuntimeICUBinder::ICU::instance().ubrk_open #define ubrk_openRules RuntimeICUBinder::ICU::instance().ubrk_openRules diff --git a/lwnode/code/escargotshim/deps/escargot/third_party/runtime_icu_binder/RuntimeICUBinder.h b/lwnode/code/escargotshim/deps/escargot/third_party/runtime_icu_binder/RuntimeICUBinder.h index 4c96294..c7ecbbc 100644 --- a/lwnode/code/escargotshim/deps/escargot/third_party/runtime_icu_binder/RuntimeICUBinder.h +++ b/lwnode/code/escargotshim/deps/escargot/third_party/runtime_icu_binder/RuntimeICUBinder.h @@ -107,6 +107,7 @@ namespace RuntimeICUBinder { F(udat_format, int32_t (*)(const UDateFormat*, UDate, UChar*, int32_t, UFieldPosition*, UErrorCode*), int32_t) \ F(udat_formatForFields, int32_t (*)(const UDateFormat* format, UDate, UChar*, int32_t, UFieldPositionIterator*, UErrorCode*), int32_t) \ F(udat_getCalendar, const UCalendar* (*)(const UDateFormat* fmt), const UCalendar*) \ + F(udat_toPattern, int32_t (*)(const UDateFormat *fmt, UBool localized, UChar *result, int32_t resultLength, UErrorCode *status), int32_t) \ F(uenum_count, int32_t (*)(UEnumeration * en, UErrorCode * status), int32_t) \ F(uenum_unext, const UChar* (*)(UEnumeration * en, int32_t * resultLength, UErrorCode * status), const UChar*) \ F(uenum_next, const char* (*)(UEnumeration * en, int32_t * resultLength, UErrorCode * status), const char*) \ @@ -122,6 +123,7 @@ namespace RuntimeICUBinder { F(udatpg_open, UDateTimePatternGenerator* (*)(const char* locale, UErrorCode* pErrorCode), UDateTimePatternGenerator*) \ F(udatpg_getBestPattern, int32_t (*)(UDateTimePatternGenerator * dtpg, const UChar* skeleton, int32_t length, UChar* bestPattern, int32_t capacity, UErrorCode* pErrorCode), int32_t) \ F(udatpg_getBestPatternWithOptions, int32_t (*)(UDateTimePatternGenerator*, const UChar*, int32_t, UDateTimePatternMatchOptions, UChar*, int32_t, UErrorCode*), int32_t) \ + F(udatpg_getSkeleton, int32_t (*)(UDateTimePatternGenerator *unusedDtpg, const UChar *pattern, int32_t length, UChar *skeleton, int32_t capacity, UErrorCode *pErrorCode), int32_t) \ F(unum_countAvailable, int32_t (*)(), int32_t) \ F(unum_getAvailable, const char* (*)(int32_t), const char*) \ F(unum_open, UNumberFormat* (*)(UNumberFormatStyle style, const UChar* pattern, int32_t patternLength, const char* locale, UParseError* parseErr, UErrorCode* status), UNumberFormat*) \ diff --git a/lwnode/code/escargotshim/deps/escargot/tools/debugger/tests/do_break_class.cmd b/lwnode/code/escargotshim/deps/escargot/tools/debugger/tests/do_break_class.cmd new file mode 100644 index 0000000..c2b95a5 --- /dev/null +++ b/lwnode/code/escargotshim/deps/escargot/tools/debugger/tests/do_break_class.cmd @@ -0,0 +1,20 @@ +b do_break_class.js:37 +n +b do_break_class.js:36 +c +bt +b do_break_class.js:66 +c +c +bt +b do_break_class.js:69 +c +b do_break_class.js:26 +b do_break_class.js:50 +b do_break_class.js:55 +c +c +bt +c +bt +c diff --git a/lwnode/code/escargotshim/deps/escargot/tools/debugger/tests/do_break_class.expected b/lwnode/code/escargotshim/deps/escargot/tools/debugger/tests/do_break_class.expected new file mode 100644 index 0000000..fedc20d --- /dev/null +++ b/lwnode/code/escargotshim/deps/escargot/tools/debugger/tests/do_break_class.expected @@ -0,0 +1,48 @@ +Connecting to: localhost:6501 +Connection created!!! +Stopped at tools/debugger/tests/do_break_class.js:20 +(escargot-debugger) b do_break_class.js:37 +No breakpoint found, do you want to add a pending breakpoint? (y or [n]) +(escargot-debugger) b do_break_class.js:36 +Breakpoint 1 at tools/debugger/tests/do_break_class.js:36 (in function() at line:37, col:7) +(escargot-debugger) c +Stopped at breakpoint:1 tools/debugger/tests/do_break_class.js:36 (in function() at line:37, col:7) +(escargot-debugger) bt +tools/debugger/tests/do_break_class.js:37:6 [depth:0] +tools/debugger/tests/do_break_class.js:22:14 [depth:1] +(escargot-debugger) b do_break_class.js:66 +Breakpoint 2 at tools/debugger/tests/do_break_class.js:66 (in function() at line:66, col:24) +Breakpoint 3 at tools/debugger/tests/do_break_class.js:66 (in function() at line:66, col:48) +(escargot-debugger) c +Stopped at breakpoint:2 tools/debugger/tests/do_break_class.js:66 (in function() at line:66, col:24) +(escargot-debugger) c +Stopped at breakpoint:3 tools/debugger/tests/do_break_class.js:66 (in function() at line:66, col:48) +(escargot-debugger) bt +tools/debugger/tests/do_break_class.js:66:47 [depth:0] +tools/debugger/tests/do_break_class.js:46:29 [depth:1] +(escargot-debugger) b do_break_class.js:69 +Breakpoint 4 at tools/debugger/tests/do_break_class.js:69 +(escargot-debugger) c +Stopped at breakpoint:4 tools/debugger/tests/do_break_class.js:69 +(escargot-debugger) b do_break_class.js:26 +Breakpoint 5 at tools/debugger/tests/do_break_class.js:26 (in function() at line:28, col:7) +(escargot-debugger) b do_break_class.js:50 +Breakpoint 6 at tools/debugger/tests/do_break_class.js:50 (in function() at line:50, col:16) +(escargot-debugger) b do_break_class.js:55 +Breakpoint 7 at tools/debugger/tests/do_break_class.js:55 (in constructor() at line:53, col:3) +(escargot-debugger) c +Stopped at breakpoint:7 tools/debugger/tests/do_break_class.js:55 (in constructor() at line:53, col:3) +(escargot-debugger) c +Stopped at breakpoint:5 tools/debugger/tests/do_break_class.js:26 (in function() at line:28, col:7) +(escargot-debugger) bt +tools/debugger/tests/do_break_class.js:28:6 [depth:0] +tools/debugger/tests/do_break_class.js:55:5 [depth:2] (in constructor) +tools/debugger/tests/do_break_class.js:69:9 [depth:3] +(escargot-debugger) c +Stopped at breakpoint:6 tools/debugger/tests/do_break_class.js:50 (in function() at line:50, col:16) +(escargot-debugger) bt +tools/debugger/tests/do_break_class.js:50:15 [depth:0] +tools/debugger/tests/do_break_class.js:55:5 [depth:1] (in constructor) +tools/debugger/tests/do_break_class.js:69:9 [depth:2] +(escargot-debugger) c +Connection closed. diff --git a/lwnode/code/escargotshim/deps/escargot/tools/debugger/tests/do_step_class.cmd b/lwnode/code/escargotshim/deps/escargot/tools/debugger/tests/do_step_class.cmd new file mode 100644 index 0000000..ffb6682 --- /dev/null +++ b/lwnode/code/escargotshim/deps/escargot/tools/debugger/tests/do_step_class.cmd @@ -0,0 +1,28 @@ +s +bt +s +s +s +s +bt +s +s +s +s +s +s +s +bt +s +s +s +s +s +s +bt +s +s +s +s +s +s diff --git a/lwnode/code/escargotshim/deps/escargot/tools/debugger/tests/do_step_class.expected b/lwnode/code/escargotshim/deps/escargot/tools/debugger/tests/do_step_class.expected new file mode 100644 index 0000000..dafa14c --- /dev/null +++ b/lwnode/code/escargotshim/deps/escargot/tools/debugger/tests/do_step_class.expected @@ -0,0 +1,65 @@ +Connecting to: localhost:6501 +Connection created!!! +Stopped at tools/debugger/tests/do_step_class.js:20 +(escargot-debugger) s +Stopped at tools/debugger/tests/do_step_class.js:36 (in function() at line:37, col:7) +(escargot-debugger) bt +tools/debugger/tests/do_step_class.js:37:6 [depth:0] +tools/debugger/tests/do_step_class.js:22:14 [depth:1] +(escargot-debugger) s +Stopped at tools/debugger/tests/do_step_class.js:40 (in function() at line:42, col:7) +(escargot-debugger) s +Stopped at tools/debugger/tests/do_step_class.js:43 (in function() at line:43, col:23) +(escargot-debugger) s +Stopped at tools/debugger/tests/do_step_class.js:43 (in function() at line:43, col:46) +(escargot-debugger) s +Stopped at tools/debugger/tests/do_step_class.js:60 (in function() at line:61, col:7) +(escargot-debugger) bt +tools/debugger/tests/do_step_class.js:61:6 [depth:0] +tools/debugger/tests/do_step_class.js:46:29 [depth:1] +(escargot-debugger) s +Stopped at tools/debugger/tests/do_step_class.js:64 (in function() at line:65, col:7) +(escargot-debugger) s +Stopped at tools/debugger/tests/do_step_class.js:66 (in function() at line:66, col:24) +(escargot-debugger) s +Stopped at tools/debugger/tests/do_step_class.js:66 (in function() at line:66, col:48) +(escargot-debugger) s +Stopped at tools/debugger/tests/do_step_class.js:69 +(escargot-debugger) s +Stopped at tools/debugger/tests/do_step_class.js:54 (in constructor() at line:53, col:3) +(escargot-debugger) s +Stopped at tools/debugger/tests/do_step_class.js:55 (in constructor() at line:53, col:3) +(escargot-debugger) s +Stopped at tools/debugger/tests/do_step_class.js:23 (in function() at line:24, col:7) +(escargot-debugger) bt +tools/debugger/tests/do_step_class.js:24:6 [depth:0] +tools/debugger/tests/do_step_class.js:55:5 [depth:2] (in constructor) +tools/debugger/tests/do_step_class.js:69:9 [depth:3] +(escargot-debugger) s +Stopped at tools/debugger/tests/do_step_class.js:26 (in function() at line:28, col:7) +(escargot-debugger) s +Stopped at tools/debugger/tests/do_step_class.js:29 (in function() at line:29, col:15) +(escargot-debugger) s +Stopped at tools/debugger/tests/do_step_class.js:29 (in function() at line:29, col:30) +(escargot-debugger) s +Stopped at tools/debugger/tests/do_step_class.js:32 (in constructor() at line:31, col:3) +(escargot-debugger) s +Stopped at tools/debugger/tests/do_step_class.js:33 (in constructor() at line:31, col:3) +(escargot-debugger) s +Stopped at tools/debugger/tests/do_step_class.js:47 (in function() at line:48, col:7) +(escargot-debugger) bt +tools/debugger/tests/do_step_class.js:48:6 [depth:0] +tools/debugger/tests/do_step_class.js:55:5 [depth:1] (in constructor) +tools/debugger/tests/do_step_class.js:69:9 [depth:2] +(escargot-debugger) s +Stopped at tools/debugger/tests/do_step_class.js:50 (in function() at line:50, col:16) +(escargot-debugger) s +Stopped at tools/debugger/tests/do_step_class.js:51 (in function() at line:51, col:16) +(escargot-debugger) s +Stopped at tools/debugger/tests/do_step_class.js:51 (in function() at line:51, col:31) +(escargot-debugger) s +Stopped at tools/debugger/tests/do_step_class.js:56 (in constructor() at line:53, col:3) +(escargot-debugger) s +Stopped at tools/debugger/tests/do_step_class.js:57 (in constructor() at line:53, col:3) +(escargot-debugger) s +Connection closed. diff --git a/lwnode/code/escargotshim/deps/minizip/crypt.h b/lwnode/code/escargotshim/deps/minizip/crypt.h new file mode 100644 index 0000000..1e9e820 --- /dev/null +++ b/lwnode/code/escargotshim/deps/minizip/crypt.h @@ -0,0 +1,131 @@ +/* crypt.h -- base code for crypt/uncrypt ZIPfile + + + Version 1.01e, February 12th, 2005 + + Copyright (C) 1998-2005 Gilles Vollant + + This code is a modified version of crypting code in Infozip distribution + + The encryption/decryption parts of this source code (as opposed to the + non-echoing password parts) were originally written in Europe. The + whole source package can be freely distributed, including from the USA. + (Prior to January 2000, re-export from the US was a violation of US law.) + + This encryption code is a direct transcription of the algorithm from + Roger Schlafly, described by Phil Katz in the file appnote.txt. This + file (appnote.txt) is distributed with the PKZIP program (even in the + version without encryption capabilities). + + If you don't need crypting in your application, just define symbols + NOCRYPT and NOUNCRYPT. + + This code support the "Traditional PKWARE Encryption". + + The new AES encryption added on Zip format by Winzip (see the page + http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong + Encryption is not supported. +*/ + +#define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8)) + +/*********************************************************************** + * Return the next byte in the pseudo-random sequence + */ +static int decrypt_byte(unsigned long* pkeys, const z_crc_t* pcrc_32_tab) +{ + unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an + * unpredictable manner on 16-bit systems; not a problem + * with any known compiler so far, though */ + + temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2; + return (int)(((temp * (temp ^ 1)) >> 8) & 0xff); +} + +/*********************************************************************** + * Update the encryption keys with the next byte of plain text + */ +static int update_keys(unsigned long* pkeys,const z_crc_t* pcrc_32_tab,int c) +{ + (*(pkeys+0)) = CRC32((*(pkeys+0)), c); + (*(pkeys+1)) += (*(pkeys+0)) & 0xff; + (*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1; + { + register int keyshift = (int)((*(pkeys+1)) >> 24); + (*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift); + } + return c; +} + + +/*********************************************************************** + * Initialize the encryption keys and the random header according to + * the given password. + */ +static void init_keys(const char* passwd,unsigned long* pkeys,const z_crc_t* pcrc_32_tab) +{ + *(pkeys+0) = 305419896L; + *(pkeys+1) = 591751049L; + *(pkeys+2) = 878082192L; + while (*passwd != '\0') { + update_keys(pkeys,pcrc_32_tab,(int)*passwd); + passwd++; + } +} + +#define zdecode(pkeys,pcrc_32_tab,c) \ + (update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab))) + +#define zencode(pkeys,pcrc_32_tab,c,t) \ + (t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), t^(c)) + +#ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED + +#define RAND_HEAD_LEN 12 + /* "last resort" source for second part of crypt seed pattern */ +# ifndef ZCR_SEED2 +# define ZCR_SEED2 3141592654UL /* use PI as default pattern */ +# endif + +static int crypthead(const char* passwd, /* password string */ + unsigned char* buf, /* where to write header */ + int bufSize, + unsigned long* pkeys, + const z_crc_t* pcrc_32_tab, + unsigned long crcForCrypting) +{ + int n; /* index in random header */ + int t; /* temporary */ + int c; /* random byte */ + unsigned char header[RAND_HEAD_LEN-2]; /* random header */ + static unsigned calls = 0; /* ensure different random header each time */ + + if (bufSize> 7) & 0xff; + header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t); + } + /* Encrypt random header (last two bytes is high word of crc) */ + init_keys(passwd, pkeys, pcrc_32_tab); + for (n = 0; n < RAND_HEAD_LEN-2; n++) + { + buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t); + } + buf[n++] = (unsigned char)zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t); + buf[n++] = (unsigned char)zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t); + return n; +} + +#endif diff --git a/lwnode/code/escargotshim/deps/minizip/ioapi.c b/lwnode/code/escargotshim/deps/minizip/ioapi.c new file mode 100644 index 0000000..543910b --- /dev/null +++ b/lwnode/code/escargotshim/deps/minizip/ioapi.c @@ -0,0 +1,247 @@ +/* ioapi.h -- IO base function header for compress/uncompress .zip + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications for Zip64 support + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + + For more info read MiniZip_info.txt + +*/ + +#if defined(_WIN32) && (!(defined(_CRT_SECURE_NO_WARNINGS))) + #define _CRT_SECURE_NO_WARNINGS +#endif + +#if defined(__APPLE__) || defined(__Fuchsia__) || defined(IOAPI_NO_64) +// In darwin and perhaps other BSD variants off_t is a 64 bit value, hence no need for specific 64 bit functions +#define FOPEN_FUNC(filename, mode) fopen(filename, mode) +#define FTELLO_FUNC(stream) ftello(stream) +#define FSEEKO_FUNC(stream, offset, origin) fseeko(stream, offset, origin) +#else +#define FOPEN_FUNC(filename, mode) fopen64(filename, mode) +#define FTELLO_FUNC(stream) ftello64(stream) +#define FSEEKO_FUNC(stream, offset, origin) fseeko64(stream, offset, origin) +#endif + + +#include "ioapi.h" + +voidpf call_zopen64 (const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode) +{ + if (pfilefunc->zfile_func64.zopen64_file != NULL) + return (*(pfilefunc->zfile_func64.zopen64_file)) (pfilefunc->zfile_func64.opaque,filename,mode); + else + { + return (*(pfilefunc->zopen32_file))(pfilefunc->zfile_func64.opaque,(const char*)filename,mode); + } +} + +long call_zseek64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin) +{ + if (pfilefunc->zfile_func64.zseek64_file != NULL) + return (*(pfilefunc->zfile_func64.zseek64_file)) (pfilefunc->zfile_func64.opaque,filestream,offset,origin); + else + { + uLong offsetTruncated = (uLong)offset; + if (offsetTruncated != offset) + return -1; + else + return (*(pfilefunc->zseek32_file))(pfilefunc->zfile_func64.opaque,filestream,offsetTruncated,origin); + } +} + +ZPOS64_T call_ztell64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream) +{ + if (pfilefunc->zfile_func64.zseek64_file != NULL) + return (*(pfilefunc->zfile_func64.ztell64_file)) (pfilefunc->zfile_func64.opaque,filestream); + else + { + uLong tell_uLong = (*(pfilefunc->ztell32_file))(pfilefunc->zfile_func64.opaque,filestream); + if ((tell_uLong) == MAXU32) + return (ZPOS64_T)-1; + else + return tell_uLong; + } +} + +void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32) +{ + p_filefunc64_32->zfile_func64.zopen64_file = NULL; + p_filefunc64_32->zopen32_file = p_filefunc32->zopen_file; + p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file; + p_filefunc64_32->zfile_func64.zread_file = p_filefunc32->zread_file; + p_filefunc64_32->zfile_func64.zwrite_file = p_filefunc32->zwrite_file; + p_filefunc64_32->zfile_func64.ztell64_file = NULL; + p_filefunc64_32->zfile_func64.zseek64_file = NULL; + p_filefunc64_32->zfile_func64.zclose_file = p_filefunc32->zclose_file; + p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file; + p_filefunc64_32->zfile_func64.opaque = p_filefunc32->opaque; + p_filefunc64_32->zseek32_file = p_filefunc32->zseek_file; + p_filefunc64_32->ztell32_file = p_filefunc32->ztell_file; +} + + + +static voidpf ZCALLBACK fopen_file_func OF((voidpf opaque, const char* filename, int mode)); +static uLong ZCALLBACK fread_file_func OF((voidpf opaque, voidpf stream, void* buf, uLong size)); +static uLong ZCALLBACK fwrite_file_func OF((voidpf opaque, voidpf stream, const void* buf,uLong size)); +static ZPOS64_T ZCALLBACK ftell64_file_func OF((voidpf opaque, voidpf stream)); +static long ZCALLBACK fseek64_file_func OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin)); +static int ZCALLBACK fclose_file_func OF((voidpf opaque, voidpf stream)); +static int ZCALLBACK ferror_file_func OF((voidpf opaque, voidpf stream)); + +static voidpf ZCALLBACK fopen_file_func (voidpf opaque, const char* filename, int mode) +{ + FILE* file = NULL; + const char* mode_fopen = NULL; + if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ) + mode_fopen = "rb"; + else + if (mode & ZLIB_FILEFUNC_MODE_EXISTING) + mode_fopen = "r+b"; + else + if (mode & ZLIB_FILEFUNC_MODE_CREATE) + mode_fopen = "wb"; + + if ((filename!=NULL) && (mode_fopen != NULL)) + file = fopen(filename, mode_fopen); + return file; +} + +static voidpf ZCALLBACK fopen64_file_func (voidpf opaque, const void* filename, int mode) +{ + FILE* file = NULL; + const char* mode_fopen = NULL; + if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ) + mode_fopen = "rb"; + else + if (mode & ZLIB_FILEFUNC_MODE_EXISTING) + mode_fopen = "r+b"; + else + if (mode & ZLIB_FILEFUNC_MODE_CREATE) + mode_fopen = "wb"; + + if ((filename!=NULL) && (mode_fopen != NULL)) + file = FOPEN_FUNC((const char*)filename, mode_fopen); + return file; +} + + +static uLong ZCALLBACK fread_file_func (voidpf opaque, voidpf stream, void* buf, uLong size) +{ + uLong ret; + ret = (uLong)fread(buf, 1, (size_t)size, (FILE *)stream); + return ret; +} + +static uLong ZCALLBACK fwrite_file_func (voidpf opaque, voidpf stream, const void* buf, uLong size) +{ + uLong ret; + ret = (uLong)fwrite(buf, 1, (size_t)size, (FILE *)stream); + return ret; +} + +static long ZCALLBACK ftell_file_func (voidpf opaque, voidpf stream) +{ + long ret; + ret = ftell((FILE *)stream); + return ret; +} + + +static ZPOS64_T ZCALLBACK ftell64_file_func (voidpf opaque, voidpf stream) +{ + ZPOS64_T ret; + ret = FTELLO_FUNC((FILE *)stream); + return ret; +} + +static long ZCALLBACK fseek_file_func (voidpf opaque, voidpf stream, uLong offset, int origin) +{ + int fseek_origin=0; + long ret; + switch (origin) + { + case ZLIB_FILEFUNC_SEEK_CUR : + fseek_origin = SEEK_CUR; + break; + case ZLIB_FILEFUNC_SEEK_END : + fseek_origin = SEEK_END; + break; + case ZLIB_FILEFUNC_SEEK_SET : + fseek_origin = SEEK_SET; + break; + default: return -1; + } + ret = 0; + if (fseek((FILE *)stream, offset, fseek_origin) != 0) + ret = -1; + return ret; +} + +static long ZCALLBACK fseek64_file_func (voidpf opaque, voidpf stream, ZPOS64_T offset, int origin) +{ + int fseek_origin=0; + long ret; + switch (origin) + { + case ZLIB_FILEFUNC_SEEK_CUR : + fseek_origin = SEEK_CUR; + break; + case ZLIB_FILEFUNC_SEEK_END : + fseek_origin = SEEK_END; + break; + case ZLIB_FILEFUNC_SEEK_SET : + fseek_origin = SEEK_SET; + break; + default: return -1; + } + ret = 0; + + if(FSEEKO_FUNC((FILE *)stream, offset, fseek_origin) != 0) + ret = -1; + + return ret; +} + + +static int ZCALLBACK fclose_file_func (voidpf opaque, voidpf stream) +{ + int ret; + ret = fclose((FILE *)stream); + return ret; +} + +static int ZCALLBACK ferror_file_func (voidpf opaque, voidpf stream) +{ + int ret; + ret = ferror((FILE *)stream); + return ret; +} + +void fill_fopen_filefunc (pzlib_filefunc_def) + zlib_filefunc_def* pzlib_filefunc_def; +{ + pzlib_filefunc_def->zopen_file = fopen_file_func; + pzlib_filefunc_def->zread_file = fread_file_func; + pzlib_filefunc_def->zwrite_file = fwrite_file_func; + pzlib_filefunc_def->ztell_file = ftell_file_func; + pzlib_filefunc_def->zseek_file = fseek_file_func; + pzlib_filefunc_def->zclose_file = fclose_file_func; + pzlib_filefunc_def->zerror_file = ferror_file_func; + pzlib_filefunc_def->opaque = NULL; +} + +void fill_fopen64_filefunc (zlib_filefunc64_def* pzlib_filefunc_def) +{ + pzlib_filefunc_def->zopen64_file = fopen64_file_func; + pzlib_filefunc_def->zread_file = fread_file_func; + pzlib_filefunc_def->zwrite_file = fwrite_file_func; + pzlib_filefunc_def->ztell64_file = ftell64_file_func; + pzlib_filefunc_def->zseek64_file = fseek64_file_func; + pzlib_filefunc_def->zclose_file = fclose_file_func; + pzlib_filefunc_def->zerror_file = ferror_file_func; + pzlib_filefunc_def->opaque = NULL; +} diff --git a/lwnode/code/escargotshim/deps/minizip/ioapi.h b/lwnode/code/escargotshim/deps/minizip/ioapi.h new file mode 100644 index 0000000..8dcbdb0 --- /dev/null +++ b/lwnode/code/escargotshim/deps/minizip/ioapi.h @@ -0,0 +1,208 @@ +/* ioapi.h -- IO base function header for compress/uncompress .zip + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications for Zip64 support + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + + For more info read MiniZip_info.txt + + Changes + + Oct-2009 - Defined ZPOS64_T to fpos_t on windows and u_int64_t on linux. (might need to find a better why for this) + Oct-2009 - Change to fseeko64, ftello64 and fopen64 so large files would work on linux. + More if/def section may be needed to support other platforms + Oct-2009 - Defined fxxxx64 calls to normal fopen/ftell/fseek so they would compile on windows. + (but you should use iowin32.c for windows instead) + +*/ + +#ifndef _ZLIBIOAPI64_H +#define _ZLIBIOAPI64_H + +#if (!defined(_WIN32)) && (!defined(WIN32)) && (!defined(__APPLE__)) + + // Linux needs this to support file operation on files larger then 4+GB + // But might need better if/def to select just the platforms that needs them. + + #ifndef __USE_FILE_OFFSET64 + #define __USE_FILE_OFFSET64 + #endif + #ifndef __USE_LARGEFILE64 + #define __USE_LARGEFILE64 + #endif + #ifndef _LARGEFILE64_SOURCE + #define _LARGEFILE64_SOURCE + #endif + #ifndef _FILE_OFFSET_BIT + #define _FILE_OFFSET_BIT 64 + #endif + +#endif + +#include +#include +#include "zlib.h" + +#if defined(USE_FILE32API) +#define fopen64 fopen +#define ftello64 ftell +#define fseeko64 fseek +#else +#ifdef __FreeBSD__ +#define fopen64 fopen +#define ftello64 ftello +#define fseeko64 fseeko +#endif +#ifdef _MSC_VER + #define fopen64 fopen + #if (_MSC_VER >= 1400) && (!(defined(NO_MSCVER_FILE64_FUNC))) + #define ftello64 _ftelli64 + #define fseeko64 _fseeki64 + #else // old MSC + #define ftello64 ftell + #define fseeko64 fseek + #endif +#endif +#endif + +/* +#ifndef ZPOS64_T + #ifdef _WIN32 + #define ZPOS64_T fpos_t + #else + #include + #define ZPOS64_T uint64_t + #endif +#endif +*/ + +#ifdef HAVE_MINIZIP64_CONF_H +#include "mz64conf.h" +#endif + +/* a type choosen by DEFINE */ +#ifdef HAVE_64BIT_INT_CUSTOM +typedef 64BIT_INT_CUSTOM_TYPE ZPOS64_T; +#else +#ifdef HAS_STDINT_H +#include "stdint.h" +typedef uint64_t ZPOS64_T; +#else + +/* Maximum unsigned 32-bit value used as placeholder for zip64 */ +#define MAXU32 0xffffffff + +#if defined(_MSC_VER) || defined(__BORLANDC__) +typedef unsigned __int64 ZPOS64_T; +#else +typedef unsigned long long int ZPOS64_T; +#endif +#endif +#endif + + + +#ifdef __cplusplus +extern "C" { +#endif + + +#define ZLIB_FILEFUNC_SEEK_CUR (1) +#define ZLIB_FILEFUNC_SEEK_END (2) +#define ZLIB_FILEFUNC_SEEK_SET (0) + +#define ZLIB_FILEFUNC_MODE_READ (1) +#define ZLIB_FILEFUNC_MODE_WRITE (2) +#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3) + +#define ZLIB_FILEFUNC_MODE_EXISTING (4) +#define ZLIB_FILEFUNC_MODE_CREATE (8) + + +#ifndef ZCALLBACK + #if (defined(WIN32) || defined(_WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK) + #define ZCALLBACK CALLBACK + #else + #define ZCALLBACK + #endif +#endif + + + + +typedef voidpf (ZCALLBACK *open_file_func) OF((voidpf opaque, const char* filename, int mode)); +typedef uLong (ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size)); +typedef uLong (ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void* buf, uLong size)); +typedef int (ZCALLBACK *close_file_func) OF((voidpf opaque, voidpf stream)); +typedef int (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream)); + +typedef long (ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream)); +typedef long (ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin)); + + +/* here is the "old" 32 bits structure structure */ +typedef struct zlib_filefunc_def_s +{ + open_file_func zopen_file; + read_file_func zread_file; + write_file_func zwrite_file; + tell_file_func ztell_file; + seek_file_func zseek_file; + close_file_func zclose_file; + testerror_file_func zerror_file; + voidpf opaque; +} zlib_filefunc_def; + +typedef ZPOS64_T (ZCALLBACK *tell64_file_func) OF((voidpf opaque, voidpf stream)); +typedef long (ZCALLBACK *seek64_file_func) OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin)); +typedef voidpf (ZCALLBACK *open64_file_func) OF((voidpf opaque, const void* filename, int mode)); + +typedef struct zlib_filefunc64_def_s +{ + open64_file_func zopen64_file; + read_file_func zread_file; + write_file_func zwrite_file; + tell64_file_func ztell64_file; + seek64_file_func zseek64_file; + close_file_func zclose_file; + testerror_file_func zerror_file; + voidpf opaque; +} zlib_filefunc64_def; + +void fill_fopen64_filefunc OF((zlib_filefunc64_def* pzlib_filefunc_def)); +void fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def)); + +/* now internal definition, only for zip.c and unzip.h */ +typedef struct zlib_filefunc64_32_def_s +{ + zlib_filefunc64_def zfile_func64; + open_file_func zopen32_file; + tell_file_func ztell32_file; + seek_file_func zseek32_file; +} zlib_filefunc64_32_def; + + +#define ZREAD64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zread_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size)) +#define ZWRITE64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zwrite_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size)) +//#define ZTELL64(filefunc,filestream) ((*((filefunc).ztell64_file)) ((filefunc).opaque,filestream)) +//#define ZSEEK64(filefunc,filestream,pos,mode) ((*((filefunc).zseek64_file)) ((filefunc).opaque,filestream,pos,mode)) +#define ZCLOSE64(filefunc,filestream) ((*((filefunc).zfile_func64.zclose_file)) ((filefunc).zfile_func64.opaque,filestream)) +#define ZERROR64(filefunc,filestream) ((*((filefunc).zfile_func64.zerror_file)) ((filefunc).zfile_func64.opaque,filestream)) + +voidpf call_zopen64 OF((const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode)); +long call_zseek64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin)); +ZPOS64_T call_ztell64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream)); + +void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32); + +#define ZOPEN64(filefunc,filename,mode) (call_zopen64((&(filefunc)),(filename),(mode))) +#define ZTELL64(filefunc,filestream) (call_ztell64((&(filefunc)),(filestream))) +#define ZSEEK64(filefunc,filestream,pos,mode) (call_zseek64((&(filefunc)),(filestream),(pos),(mode))) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lwnode/code/escargotshim/deps/minizip/minizip.gyp b/lwnode/code/escargotshim/deps/minizip/minizip.gyp new file mode 100755 index 0000000..7b1421e --- /dev/null +++ b/lwnode/code/escargotshim/deps/minizip/minizip.gyp @@ -0,0 +1,27 @@ +{ + 'includes': ['../../common.gypi'], + 'targets': [ + { + 'target_name': 'minizip', + 'type': 'static_library', + 'sources': [ + 'unzip.c', + 'ioapi.c', + ], + 'defines': [ + 'NOUNCRYPT', + ], + 'link_settings': { + 'libraries': ['-lz'], + }, + 'direct_dependent_settings': { + 'defines': [ + 'NOUNCRYPT', + ], + 'include_dirs': [ + '.', + ], + }, + }, + ], +} diff --git a/lwnode/code/escargotshim/deps/minizip/unzip.c b/lwnode/code/escargotshim/deps/minizip/unzip.c new file mode 100644 index 0000000..c5737eb --- /dev/null +++ b/lwnode/code/escargotshim/deps/minizip/unzip.c @@ -0,0 +1,2122 @@ +/* unzip.c -- IO for uncompress .zip files using zlib + Version 1.1, February 14h, 2010 + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications of Unzip for Zip64 + Copyright (C) 2007-2008 Even Rouault + + Modifications for Zip64 support on both zip and unzip + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + + For more info read MiniZip_info.txt + + + ------------------------------------------------------------------------------------ + Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of + compatibility with older software. The following is from the original crypt.c. + Code woven in by Terry Thorsen 1/2003. + + Copyright (c) 1990-2000 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2000-Apr-09 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html + + crypt.c (full version) by Info-ZIP. Last revised: [see crypt.h] + + The encryption/decryption parts of this source code (as opposed to the + non-echoing password parts) were originally written in Europe. The + whole source package can be freely distributed, including from the USA. + (Prior to January 2000, re-export from the US was a violation of US law.) + + This encryption code is a direct transcription of the algorithm from + Roger Schlafly, described by Phil Katz in the file appnote.txt. This + file (appnote.txt) is distributed with the PKZIP program (even in the + version without encryption capabilities). + + ------------------------------------------------------------------------------------ + + Changes in unzip.c + + 2007-2008 - Even Rouault - Addition of cpl_unzGetCurrentFileZStreamPos + 2007-2008 - Even Rouault - Decoration of symbol names unz* -> cpl_unz* + 2007-2008 - Even Rouault - Remove old C style function prototypes + 2007-2008 - Even Rouault - Add unzip support for ZIP64 + + Copyright (C) 2007-2008 Even Rouault + + + Oct-2009 - Mathias Svensson - Removed cpl_* from symbol names (Even Rouault added them but since this is now moved to a new project (minizip64) I renamed them again). + Oct-2009 - Mathias Svensson - Fixed problem if uncompressed size was > 4G and compressed size was <4G + should only read the compressed/uncompressed size from the Zip64 format if + the size from normal header was 0xFFFFFFFF + Oct-2009 - Mathias Svensson - Applied some bug fixes from paches recived from Gilles Vollant + Oct-2009 - Mathias Svensson - Applied support to unzip files with compression mathod BZIP2 (bzip2 lib is required) + Patch created by Daniel Borca + + Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer + + Copyright (C) 1998 - 2010 Gilles Vollant, Even Rouault, Mathias Svensson + +*/ + + +#include +#include +#include + +#include "zlib.h" +#include "unzip.h" + +#ifdef STDC +# include +# include +# include +#endif +#ifdef NO_ERRNO_H + extern int errno; +#else +# include +#endif + + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + + +#ifndef CASESENSITIVITYDEFAULT_NO +# if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) +# define CASESENSITIVITYDEFAULT_NO +# endif +#endif + + +#ifndef UNZ_BUFSIZE +#define UNZ_BUFSIZE (16384) +#endif + +#ifndef UNZ_MAXFILENAMEINZIP +#define UNZ_MAXFILENAMEINZIP (256) +#endif + +#ifndef ALLOC +# define ALLOC(size) (malloc(size)) +#endif +#ifndef TRYFREE +# define TRYFREE(p) {if (p) free(p);} +#endif + +#define SIZECENTRALDIRITEM (0x2e) +#define SIZEZIPLOCALHEADER (0x1e) + + +const char unz_copyright[] = + " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll"; + +/* unz_file_info_interntal contain internal info about a file in zipfile*/ +typedef struct unz_file_info64_internal_s +{ + ZPOS64_T offset_curfile;/* relative offset of local header 8 bytes */ +} unz_file_info64_internal; + + +/* file_in_zip_read_info_s contain internal information about a file in zipfile, + when reading and decompress it */ +typedef struct +{ + char *read_buffer; /* internal buffer for compressed data */ + z_stream stream; /* zLib stream structure for inflate */ + +#ifdef HAVE_BZIP2 + bz_stream bstream; /* bzLib stream structure for bziped */ +#endif + + ZPOS64_T pos_in_zipfile; /* position in byte on the zipfile, for fseek*/ + uLong stream_initialised; /* flag set if stream structure is initialised*/ + + ZPOS64_T offset_local_extrafield;/* offset of the local extra field */ + uInt size_local_extrafield;/* size of the local extra field */ + ZPOS64_T pos_local_extrafield; /* position in the local extra field in read*/ + ZPOS64_T total_out_64; + + uLong crc32; /* crc32 of all data uncompressed */ + uLong crc32_wait; /* crc32 we must obtain after decompress all */ + ZPOS64_T rest_read_compressed; /* number of byte to be decompressed */ + ZPOS64_T rest_read_uncompressed;/*number of byte to be obtained after decomp*/ + zlib_filefunc64_32_def z_filefunc; + voidpf filestream; /* io structore of the zipfile */ + uLong compression_method; /* compression method (0==store) */ + ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ + int raw; +} file_in_zip64_read_info_s; + + +/* unz64_s contain internal information about the zipfile +*/ +typedef struct +{ + zlib_filefunc64_32_def z_filefunc; + int is64bitOpenFunction; + voidpf filestream; /* io structore of the zipfile */ + unz_global_info64 gi; /* public global information */ + ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ + ZPOS64_T num_file; /* number of the current file in the zipfile*/ + ZPOS64_T pos_in_central_dir; /* pos of the current file in the central dir*/ + ZPOS64_T current_file_ok; /* flag about the usability of the current file*/ + ZPOS64_T central_pos; /* position of the beginning of the central dir*/ + + ZPOS64_T size_central_dir; /* size of the central directory */ + ZPOS64_T offset_central_dir; /* offset of start of central directory with + respect to the starting disk number */ + + unz_file_info64 cur_file_info; /* public info about the current file in zip*/ + unz_file_info64_internal cur_file_info_internal; /* private info about it*/ + file_in_zip64_read_info_s* pfile_in_zip_read; /* structure about the current + file if we are decompressing it */ + int encrypted; + + int isZip64; + +# ifndef NOUNCRYPT + unsigned long keys[3]; /* keys defining the pseudo-random sequence */ + const z_crc_t* pcrc_32_tab; +# endif +} unz64_s; + + +#ifndef NOUNCRYPT +#include "crypt.h" +#endif + +/* =========================================================================== + Read a byte from a gz_stream; update next_in and avail_in. Return EOF + for end of file. + IN assertion: the stream s has been successfully opened for reading. +*/ + + +local int unz64local_getByte OF(( + const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + int *pi)); + +local int unz64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi) +{ + unsigned char c; + int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1); + if (err==1) + { + *pi = (int)c; + return UNZ_OK; + } + else + { + if (ZERROR64(*pzlib_filefunc_def,filestream)) + return UNZ_ERRNO; + else + return UNZ_EOF; + } +} + + +/* =========================================================================== + Reads a long in LSB order from the given gz_stream. Sets +*/ +local int unz64local_getShort OF(( + const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + uLong *pX)); + +local int unz64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + uLong *pX) +{ + uLong x ; + int i = 0; + int err; + + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x = (uLong)i; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((uLong)i)<<8; + + if (err==UNZ_OK) + *pX = x; + else + *pX = 0; + return err; +} + +local int unz64local_getLong OF(( + const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + uLong *pX)); + +local int unz64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + uLong *pX) +{ + uLong x ; + int i = 0; + int err; + + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x = (uLong)i; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((uLong)i)<<8; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((uLong)i)<<16; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<24; + + if (err==UNZ_OK) + *pX = x; + else + *pX = 0; + return err; +} + +local int unz64local_getLong64 OF(( + const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + ZPOS64_T *pX)); + + +local int unz64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + ZPOS64_T *pX) +{ + ZPOS64_T x ; + int i = 0; + int err; + + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x = (ZPOS64_T)i; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((ZPOS64_T)i)<<8; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((ZPOS64_T)i)<<16; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((ZPOS64_T)i)<<24; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((ZPOS64_T)i)<<32; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((ZPOS64_T)i)<<40; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((ZPOS64_T)i)<<48; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((ZPOS64_T)i)<<56; + + if (err==UNZ_OK) + *pX = x; + else + *pX = 0; + return err; +} + +/* My own strcmpi / strcasecmp */ +local int strcmpcasenosensitive_internal (const char* fileName1, const char* fileName2) +{ + for (;;) + { + char c1=*(fileName1++); + char c2=*(fileName2++); + if ((c1>='a') && (c1<='z')) + c1 -= 0x20; + if ((c2>='a') && (c2<='z')) + c2 -= 0x20; + if (c1=='\0') + return ((c2=='\0') ? 0 : -1); + if (c2=='\0') + return 1; + if (c1c2) + return 1; + } +} + + +#ifdef CASESENSITIVITYDEFAULT_NO +#define CASESENSITIVITYDEFAULTVALUE 2 +#else +#define CASESENSITIVITYDEFAULTVALUE 1 +#endif + +#ifndef STRCMPCASENOSENTIVEFUNCTION +#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal +#endif + +/* + Compare two filename (fileName1,fileName2). + If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) + If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi + or strcasecmp) + If iCaseSenisivity = 0, case sensitivity is defaut of your operating system + (like 1 on Unix, 2 on Windows) + +*/ +extern int ZEXPORT unzStringFileNameCompare (const char* fileName1, + const char* fileName2, + int iCaseSensitivity) + +{ + if (iCaseSensitivity==0) + iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE; + + if (iCaseSensitivity==1) + return strcmp(fileName1,fileName2); + + return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2); +} + +#ifndef BUFREADCOMMENT +#define BUFREADCOMMENT (0x400) +#endif + +/* + Locate the Central directory of a zipfile (at the end, just before + the global comment) +*/ +local ZPOS64_T unz64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)); +local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) +{ + unsigned char* buf; + ZPOS64_T uSizeFile; + ZPOS64_T uBackRead; + ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ + ZPOS64_T uPosFound=0; + + if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) + return 0; + + + uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); + + if (uMaxBack>uSizeFile) + uMaxBack = uSizeFile; + + buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); + if (buf==NULL) + return 0; + + uBackRead = 4; + while (uBackReaduMaxBack) + uBackRead = uMaxBack; + else + uBackRead+=BUFREADCOMMENT; + uReadPos = uSizeFile-uBackRead ; + + uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? + (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); + if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) + break; + + if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) + break; + + for (i=(int)uReadSize-3; (i--)>0;) + if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && + ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) + { + uPosFound = uReadPos+i; + break; + } + + if (uPosFound!=0) + break; + } + TRYFREE(buf); + return uPosFound; +} + + +/* + Locate the Central directory 64 of a zipfile (at the end, just before + the global comment) +*/ +local ZPOS64_T unz64local_SearchCentralDir64 OF(( + const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream)); + +local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream) +{ + unsigned char* buf; + ZPOS64_T uSizeFile; + ZPOS64_T uBackRead; + ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ + ZPOS64_T uPosFound=0; + uLong uL; + ZPOS64_T relativeOffset; + + if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) + return 0; + + + uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); + + if (uMaxBack>uSizeFile) + uMaxBack = uSizeFile; + + buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); + if (buf==NULL) + return 0; + + uBackRead = 4; + while (uBackReaduMaxBack) + uBackRead = uMaxBack; + else + uBackRead+=BUFREADCOMMENT; + uReadPos = uSizeFile-uBackRead ; + + uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? + (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); + if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) + break; + + if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) + break; + + for (i=(int)uReadSize-3; (i--)>0;) + if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && + ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07)) + { + uPosFound = uReadPos+i; + break; + } + + if (uPosFound!=0) + break; + } + TRYFREE(buf); + if (uPosFound == 0) + return 0; + + /* Zip64 end of central directory locator */ + if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0) + return 0; + + /* the signature, already checked */ + if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) + return 0; + + /* number of the disk with the start of the zip64 end of central directory */ + if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) + return 0; + if (uL != 0) + return 0; + + /* relative offset of the zip64 end of central directory record */ + if (unz64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=UNZ_OK) + return 0; + + /* total number of disks */ + if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) + return 0; + if (uL != 1) + return 0; + + /* Goto end of central directory record */ + if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0) + return 0; + + /* the signature */ + if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) + return 0; + + if (uL != 0x06064b50) + return 0; + + return relativeOffset; +} + +/* + Open a Zip file. path contain the full pathname (by example, + on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer + "zlib/zlib114.zip". + If the zipfile cannot be opened (file doesn't exist or in not valid), the + return value is NULL. + Else, the return value is a unzFile Handle, usable with other function + of this unzip package. +*/ +local unzFile unzOpenInternal (const void *path, + zlib_filefunc64_32_def* pzlib_filefunc64_32_def, + int is64bitOpenFunction) +{ + unz64_s us; + unz64_s *s; + ZPOS64_T central_pos; + uLong uL; + + uLong number_disk; /* number of the current dist, used for + spaning ZIP, unsupported, always 0*/ + uLong number_disk_with_CD; /* number the the disk with central dir, used + for spaning ZIP, unsupported, always 0*/ + ZPOS64_T number_entry_CD; /* total number of entries in + the central dir + (same than number_entry on nospan) */ + + int err=UNZ_OK; + + if (unz_copyright[0]!=' ') + return NULL; + + us.z_filefunc.zseek32_file = NULL; + us.z_filefunc.ztell32_file = NULL; + if (pzlib_filefunc64_32_def==NULL) + fill_fopen64_filefunc(&us.z_filefunc.zfile_func64); + else + us.z_filefunc = *pzlib_filefunc64_32_def; + us.is64bitOpenFunction = is64bitOpenFunction; + + + + us.filestream = ZOPEN64(us.z_filefunc, + path, + ZLIB_FILEFUNC_MODE_READ | + ZLIB_FILEFUNC_MODE_EXISTING); + if (us.filestream==NULL) + return NULL; + + central_pos = unz64local_SearchCentralDir64(&us.z_filefunc,us.filestream); + if (central_pos) + { + uLong uS; + ZPOS64_T uL64; + + us.isZip64 = 1; + + if (ZSEEK64(us.z_filefunc, us.filestream, + central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) + err=UNZ_ERRNO; + + /* the signature, already checked */ + if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + + /* size of zip64 end of central directory record */ + if (unz64local_getLong64(&us.z_filefunc, us.filestream,&uL64)!=UNZ_OK) + err=UNZ_ERRNO; + + /* version made by */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK) + err=UNZ_ERRNO; + + /* version needed to extract */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK) + err=UNZ_ERRNO; + + /* number of this disk */ + if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK) + err=UNZ_ERRNO; + + /* number of the disk with the start of the central directory */ + if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK) + err=UNZ_ERRNO; + + /* total number of entries in the central directory on this disk */ + if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK) + err=UNZ_ERRNO; + + /* total number of entries in the central directory */ + if (unz64local_getLong64(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK) + err=UNZ_ERRNO; + + if ((number_entry_CD!=us.gi.number_entry) || + (number_disk_with_CD!=0) || + (number_disk!=0)) + err=UNZ_BADZIPFILE; + + /* size of the central directory */ + if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK) + err=UNZ_ERRNO; + + /* offset of start of central directory with respect to the + starting disk number */ + if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK) + err=UNZ_ERRNO; + + us.gi.size_comment = 0; + } + else + { + central_pos = unz64local_SearchCentralDir(&us.z_filefunc,us.filestream); + if (central_pos==0) + err=UNZ_ERRNO; + + us.isZip64 = 0; + + if (ZSEEK64(us.z_filefunc, us.filestream, + central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) + err=UNZ_ERRNO; + + /* the signature, already checked */ + if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + + /* number of this disk */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK) + err=UNZ_ERRNO; + + /* number of the disk with the start of the central directory */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK) + err=UNZ_ERRNO; + + /* total number of entries in the central dir on this disk */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + us.gi.number_entry = uL; + + /* total number of entries in the central dir */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + number_entry_CD = uL; + + if ((number_entry_CD!=us.gi.number_entry) || + (number_disk_with_CD!=0) || + (number_disk!=0)) + err=UNZ_BADZIPFILE; + + /* size of the central directory */ + if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + us.size_central_dir = uL; + + /* offset of start of central directory with respect to the + starting disk number */ + if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + us.offset_central_dir = uL; + + /* zipfile comment length */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK) + err=UNZ_ERRNO; + } + + if ((central_pospfile_in_zip_read!=NULL) + unzCloseCurrentFile(file); + + ZCLOSE64(s->z_filefunc, s->filestream); + TRYFREE(s); + return UNZ_OK; +} + + +/* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. */ +extern int ZEXPORT unzGetGlobalInfo64 (unzFile file, unz_global_info64* pglobal_info) +{ + unz64_s* s; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + *pglobal_info=s->gi; + return UNZ_OK; +} + +extern int ZEXPORT unzGetGlobalInfo (unzFile file, unz_global_info* pglobal_info32) +{ + unz64_s* s; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + /* to do : check if number_entry is not truncated */ + pglobal_info32->number_entry = (uLong)s->gi.number_entry; + pglobal_info32->size_comment = s->gi.size_comment; + return UNZ_OK; +} +/* + Translate date/time from Dos format to tm_unz (readable more easilty) +*/ +local void unz64local_DosDateToTmuDate (ZPOS64_T ulDosDate, tm_unz* ptm) +{ + ZPOS64_T uDate; + uDate = (ZPOS64_T)(ulDosDate>>16); + ptm->tm_mday = (uInt)(uDate&0x1f) ; + ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ; + ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ; + + ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800); + ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ; + ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ; +} + +/* + Get Info about the current file in the zipfile, with internal only info +*/ +local int unz64local_GetCurrentFileInfoInternal OF((unzFile file, + unz_file_info64 *pfile_info, + unz_file_info64_internal + *pfile_info_internal, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize)); + +local int unz64local_GetCurrentFileInfoInternal (unzFile file, + unz_file_info64 *pfile_info, + unz_file_info64_internal + *pfile_info_internal, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize) +{ + unz64_s* s; + unz_file_info64 file_info; + unz_file_info64_internal file_info_internal; + int err=UNZ_OK; + uLong uMagic; + long lSeek=0; + uLong uL; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + if (ZSEEK64(s->z_filefunc, s->filestream, + s->pos_in_central_dir+s->byte_before_the_zipfile, + ZLIB_FILEFUNC_SEEK_SET)!=0) + err=UNZ_ERRNO; + + + /* we check the magic */ + if (err==UNZ_OK) + { + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK) + err=UNZ_ERRNO; + else if (uMagic!=0x02014b50) + err=UNZ_BADZIPFILE; + } + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK) + err=UNZ_ERRNO; + + unz64local_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date); + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) + err=UNZ_ERRNO; + file_info.compressed_size = uL; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) + err=UNZ_ERRNO; + file_info.uncompressed_size = uL; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK) + err=UNZ_ERRNO; + + // relative offset of local header + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) + err=UNZ_ERRNO; + file_info_internal.offset_curfile = uL; + + lSeek+=file_info.size_filename; + if ((err==UNZ_OK) && (szFileName!=NULL)) + { + uLong uSizeRead ; + if (file_info.size_filename0) && (fileNameBufferSize>0)) + if (ZREAD64(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead) + err=UNZ_ERRNO; + lSeek -= uSizeRead; + } + + // Read extrafield + if ((err==UNZ_OK) && (extraField!=NULL)) + { + ZPOS64_T uSizeRead ; + if (file_info.size_file_extraz_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) + lSeek=0; + else + err=UNZ_ERRNO; + } + + if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0)) + if (ZREAD64(s->z_filefunc, s->filestream,extraField,(uLong)uSizeRead)!=uSizeRead) + err=UNZ_ERRNO; + + lSeek += file_info.size_file_extra - (uLong)uSizeRead; + } + else + lSeek += file_info.size_file_extra; + + + if ((err==UNZ_OK) && (file_info.size_file_extra != 0)) + { + uLong acc = 0; + + // since lSeek now points to after the extra field we need to move back + lSeek -= file_info.size_file_extra; + + if (lSeek!=0) + { + if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) + lSeek=0; + else + err=UNZ_ERRNO; + } + + while(acc < file_info.size_file_extra) + { + uLong headerId; + uLong dataSize; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&headerId) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&dataSize) != UNZ_OK) + err=UNZ_ERRNO; + + /* ZIP64 extra fields */ + if (headerId == 0x0001) + { + uLong uL; + + if(file_info.uncompressed_size == MAXU32) + { + if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK) + err=UNZ_ERRNO; + } + + if(file_info.compressed_size == MAXU32) + { + if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK) + err=UNZ_ERRNO; + } + + if(file_info_internal.offset_curfile == MAXU32) + { + /* Relative Header offset */ + if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK) + err=UNZ_ERRNO; + } + + if(file_info.disk_num_start == MAXU32) + { + /* Disk Start Number */ + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) + err=UNZ_ERRNO; + } + + } + else + { + if (ZSEEK64(s->z_filefunc, s->filestream,dataSize,ZLIB_FILEFUNC_SEEK_CUR)!=0) + err=UNZ_ERRNO; + } + + acc += 2 + 2 + dataSize; + } + } + + if ((err==UNZ_OK) && (szComment!=NULL)) + { + uLong uSizeRead ; + if (file_info.size_file_commentz_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) + lSeek=0; + else + err=UNZ_ERRNO; + } + + if ((file_info.size_file_comment>0) && (commentBufferSize>0)) + if (ZREAD64(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead) + err=UNZ_ERRNO; + lSeek+=file_info.size_file_comment - uSizeRead; + } + else + lSeek+=file_info.size_file_comment; + + + if ((err==UNZ_OK) && (pfile_info!=NULL)) + *pfile_info=file_info; + + if ((err==UNZ_OK) && (pfile_info_internal!=NULL)) + *pfile_info_internal=file_info_internal; + + return err; +} + + + +/* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. +*/ +extern int ZEXPORT unzGetCurrentFileInfo64 (unzFile file, + unz_file_info64 * pfile_info, + char * szFileName, uLong fileNameBufferSize, + void *extraField, uLong extraFieldBufferSize, + char* szComment, uLong commentBufferSize) +{ + return unz64local_GetCurrentFileInfoInternal(file,pfile_info,NULL, + szFileName,fileNameBufferSize, + extraField,extraFieldBufferSize, + szComment,commentBufferSize); +} + +extern int ZEXPORT unzGetCurrentFileInfo (unzFile file, + unz_file_info * pfile_info, + char * szFileName, uLong fileNameBufferSize, + void *extraField, uLong extraFieldBufferSize, + char* szComment, uLong commentBufferSize) +{ + int err; + unz_file_info64 file_info64; + err = unz64local_GetCurrentFileInfoInternal(file,&file_info64,NULL, + szFileName,fileNameBufferSize, + extraField,extraFieldBufferSize, + szComment,commentBufferSize); + if ((err==UNZ_OK) && (pfile_info != NULL)) + { + pfile_info->version = file_info64.version; + pfile_info->version_needed = file_info64.version_needed; + pfile_info->flag = file_info64.flag; + pfile_info->compression_method = file_info64.compression_method; + pfile_info->dosDate = file_info64.dosDate; + pfile_info->crc = file_info64.crc; + + pfile_info->size_filename = file_info64.size_filename; + pfile_info->size_file_extra = file_info64.size_file_extra; + pfile_info->size_file_comment = file_info64.size_file_comment; + + pfile_info->disk_num_start = file_info64.disk_num_start; + pfile_info->internal_fa = file_info64.internal_fa; + pfile_info->external_fa = file_info64.external_fa; + + pfile_info->tmu_date = file_info64.tmu_date, + + + pfile_info->compressed_size = (uLong)file_info64.compressed_size; + pfile_info->uncompressed_size = (uLong)file_info64.uncompressed_size; + + } + return err; +} +/* + Set the current file of the zipfile to the first file. + return UNZ_OK if there is no problem +*/ +extern int ZEXPORT unzGoToFirstFile (unzFile file) +{ + int err=UNZ_OK; + unz64_s* s; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + s->pos_in_central_dir=s->offset_central_dir; + s->num_file=0; + err=unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + s->current_file_ok = (err == UNZ_OK); + return err; +} + +/* + Set the current file of the zipfile to the next file. + return UNZ_OK if there is no problem + return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. +*/ +extern int ZEXPORT unzGoToNextFile (unzFile file) +{ + unz64_s* s; + int err; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; + if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */ + if (s->num_file+1==s->gi.number_entry) + return UNZ_END_OF_LIST_OF_FILE; + + s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename + + s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ; + s->num_file++; + err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + s->current_file_ok = (err == UNZ_OK); + return err; +} + + +/* + Try locate the file szFileName in the zipfile. + For the iCaseSensitivity signification, see unzStringFileNameCompare + + return value : + UNZ_OK if the file is found. It becomes the current file. + UNZ_END_OF_LIST_OF_FILE if the file is not found +*/ +extern int ZEXPORT unzLocateFile (unzFile file, const char *szFileName, int iCaseSensitivity) +{ + unz64_s* s; + int err; + + /* We remember the 'current' position in the file so that we can jump + * back there if we fail. + */ + unz_file_info64 cur_file_infoSaved; + unz_file_info64_internal cur_file_info_internalSaved; + ZPOS64_T num_fileSaved; + ZPOS64_T pos_in_central_dirSaved; + + + if (file==NULL) + return UNZ_PARAMERROR; + + if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP) + return UNZ_PARAMERROR; + + s=(unz64_s*)file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; + + /* Save the current state */ + num_fileSaved = s->num_file; + pos_in_central_dirSaved = s->pos_in_central_dir; + cur_file_infoSaved = s->cur_file_info; + cur_file_info_internalSaved = s->cur_file_info_internal; + + err = unzGoToFirstFile(file); + + while (err == UNZ_OK) + { + char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1]; + err = unzGetCurrentFileInfo64(file,NULL, + szCurrentFileName,sizeof(szCurrentFileName)-1, + NULL,0,NULL,0); + if (err == UNZ_OK) + { + if (unzStringFileNameCompare(szCurrentFileName, + szFileName,iCaseSensitivity)==0) + return UNZ_OK; + err = unzGoToNextFile(file); + } + } + + /* We failed, so restore the state of the 'current file' to where we + * were. + */ + s->num_file = num_fileSaved ; + s->pos_in_central_dir = pos_in_central_dirSaved ; + s->cur_file_info = cur_file_infoSaved; + s->cur_file_info_internal = cur_file_info_internalSaved; + return err; +} + + +/* +/////////////////////////////////////////// +// Contributed by Ryan Haksi (mailto://cryogen@infoserve.net) +// I need random access +// +// Further optimization could be realized by adding an ability +// to cache the directory in memory. The goal being a single +// comprehensive file read to put the file I need in a memory. +*/ + +/* +typedef struct unz_file_pos_s +{ + ZPOS64_T pos_in_zip_directory; // offset in file + ZPOS64_T num_of_file; // # of file +} unz_file_pos; +*/ + +extern int ZEXPORT unzGetFilePos64(unzFile file, unz64_file_pos* file_pos) +{ + unz64_s* s; + + if (file==NULL || file_pos==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; + + file_pos->pos_in_zip_directory = s->pos_in_central_dir; + file_pos->num_of_file = s->num_file; + + return UNZ_OK; +} + +extern int ZEXPORT unzGetFilePos( + unzFile file, + unz_file_pos* file_pos) +{ + unz64_file_pos file_pos64; + int err = unzGetFilePos64(file,&file_pos64); + if (err==UNZ_OK) + { + file_pos->pos_in_zip_directory = (uLong)file_pos64.pos_in_zip_directory; + file_pos->num_of_file = (uLong)file_pos64.num_of_file; + } + return err; +} + +extern int ZEXPORT unzGoToFilePos64(unzFile file, const unz64_file_pos* file_pos) +{ + unz64_s* s; + int err; + + if (file==NULL || file_pos==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + + /* jump to the right spot */ + s->pos_in_central_dir = file_pos->pos_in_zip_directory; + s->num_file = file_pos->num_of_file; + + /* set the current file */ + err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + /* return results */ + s->current_file_ok = (err == UNZ_OK); + return err; +} + +extern int ZEXPORT unzGoToFilePos( + unzFile file, + unz_file_pos* file_pos) +{ + unz64_file_pos file_pos64; + if (file_pos == NULL) + return UNZ_PARAMERROR; + + file_pos64.pos_in_zip_directory = file_pos->pos_in_zip_directory; + file_pos64.num_of_file = file_pos->num_of_file; + return unzGoToFilePos64(file,&file_pos64); +} + +/* +// Unzip Helper Functions - should be here? +/////////////////////////////////////////// +*/ + +/* + Read the local header of the current zipfile + Check the coherency of the local header and info in the end of central + directory about this file + store in *piSizeVar the size of extra info in local header + (filename and size of extra field data) +*/ +local int unz64local_CheckCurrentFileCoherencyHeader (unz64_s* s, uInt* piSizeVar, + ZPOS64_T * poffset_local_extrafield, + uInt * psize_local_extrafield) +{ + uLong uMagic,uData,uFlags; + uLong size_filename; + uLong size_extra_field; + int err=UNZ_OK; + + *piSizeVar = 0; + *poffset_local_extrafield = 0; + *psize_local_extrafield = 0; + + if (ZSEEK64(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile + + s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0) + return UNZ_ERRNO; + + + if (err==UNZ_OK) + { + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK) + err=UNZ_ERRNO; + else if (uMagic!=0x04034b50) + err=UNZ_BADZIPFILE; + } + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) + err=UNZ_ERRNO; +/* + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion)) + err=UNZ_BADZIPFILE; +*/ + if (unz64local_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method)) + err=UNZ_BADZIPFILE; + + if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) && +/* #ifdef HAVE_BZIP2 */ + (s->cur_file_info.compression_method!=Z_BZIP2ED) && +/* #endif */ + (s->cur_file_info.compression_method!=Z_DEFLATED)) + err=UNZ_BADZIPFILE; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */ + err=UNZ_ERRNO; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */ + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */ + err=UNZ_ERRNO; + else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */ + err=UNZ_ERRNO; + else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK) + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename)) + err=UNZ_BADZIPFILE; + + *piSizeVar += (uInt)size_filename; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK) + err=UNZ_ERRNO; + *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile + + SIZEZIPLOCALHEADER + size_filename; + *psize_local_extrafield = (uInt)size_extra_field; + + *piSizeVar += (uInt)size_extra_field; + + return err; +} + +/* + Open for reading data the current file in the zipfile. + If there is no error and the file is opened, the return value is UNZ_OK. +*/ +extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method, + int* level, int raw, const char* password) +{ + int err=UNZ_OK; + uInt iSizeVar; + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + ZPOS64_T offset_local_extrafield; /* offset of the local extra field */ + uInt size_local_extrafield; /* size of the local extra field */ +# ifndef NOUNCRYPT + char source[12]; +# else + if (password != NULL) + return UNZ_PARAMERROR; +# endif + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + if (!s->current_file_ok) + return UNZ_PARAMERROR; + + if (s->pfile_in_zip_read != NULL) + unzCloseCurrentFile(file); + + if (unz64local_CheckCurrentFileCoherencyHeader(s,&iSizeVar, &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK) + return UNZ_BADZIPFILE; + + pfile_in_zip_read_info = (file_in_zip64_read_info_s*)ALLOC(sizeof(file_in_zip64_read_info_s)); + if (pfile_in_zip_read_info==NULL) + return UNZ_INTERNALERROR; + + pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE); + pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield; + pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield; + pfile_in_zip_read_info->pos_local_extrafield=0; + pfile_in_zip_read_info->raw=raw; + + if (pfile_in_zip_read_info->read_buffer==NULL) + { + TRYFREE(pfile_in_zip_read_info); + return UNZ_INTERNALERROR; + } + + pfile_in_zip_read_info->stream_initialised=0; + + if (method!=NULL) + *method = (int)s->cur_file_info.compression_method; + + if (level!=NULL) + { + *level = 6; + switch (s->cur_file_info.flag & 0x06) + { + case 6 : *level = 1; break; + case 4 : *level = 2; break; + case 2 : *level = 9; break; + } + } + + if ((s->cur_file_info.compression_method!=0) && +/* #ifdef HAVE_BZIP2 */ + (s->cur_file_info.compression_method!=Z_BZIP2ED) && +/* #endif */ + (s->cur_file_info.compression_method!=Z_DEFLATED)) + + err=UNZ_BADZIPFILE; + + pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc; + pfile_in_zip_read_info->crc32=0; + pfile_in_zip_read_info->total_out_64=0; + pfile_in_zip_read_info->compression_method = s->cur_file_info.compression_method; + pfile_in_zip_read_info->filestream=s->filestream; + pfile_in_zip_read_info->z_filefunc=s->z_filefunc; + pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile; + + pfile_in_zip_read_info->stream.total_out = 0; + + if ((s->cur_file_info.compression_method==Z_BZIP2ED) && (!raw)) + { +#ifdef HAVE_BZIP2 + pfile_in_zip_read_info->bstream.bzalloc = (void *(*) (void *, int, int))0; + pfile_in_zip_read_info->bstream.bzfree = (free_func)0; + pfile_in_zip_read_info->bstream.opaque = (voidpf)0; + pfile_in_zip_read_info->bstream.state = (voidpf)0; + + pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; + pfile_in_zip_read_info->stream.zfree = (free_func)0; + pfile_in_zip_read_info->stream.opaque = (voidpf)0; + pfile_in_zip_read_info->stream.next_in = (voidpf)0; + pfile_in_zip_read_info->stream.avail_in = 0; + + err=BZ2_bzDecompressInit(&pfile_in_zip_read_info->bstream, 0, 0); + if (err == Z_OK) + pfile_in_zip_read_info->stream_initialised=Z_BZIP2ED; + else + { + TRYFREE(pfile_in_zip_read_info); + return err; + } +#else + pfile_in_zip_read_info->raw=1; +#endif + } + else if ((s->cur_file_info.compression_method==Z_DEFLATED) && (!raw)) + { + pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; + pfile_in_zip_read_info->stream.zfree = (free_func)0; + pfile_in_zip_read_info->stream.opaque = (voidpf)0; + pfile_in_zip_read_info->stream.next_in = 0; + pfile_in_zip_read_info->stream.avail_in = 0; + + err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS); + if (err == Z_OK) + pfile_in_zip_read_info->stream_initialised=Z_DEFLATED; + else + { + TRYFREE(pfile_in_zip_read_info); + return err; + } + /* windowBits is passed < 0 to tell that there is no zlib header. + * Note that in this case inflate *requires* an extra "dummy" byte + * after the compressed stream in order to complete decompression and + * return Z_STREAM_END. + * In unzip, i don't wait absolutely Z_STREAM_END because I known the + * size of both compressed and uncompressed data + */ + } + pfile_in_zip_read_info->rest_read_compressed = + s->cur_file_info.compressed_size ; + pfile_in_zip_read_info->rest_read_uncompressed = + s->cur_file_info.uncompressed_size ; + + + pfile_in_zip_read_info->pos_in_zipfile = + s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + + iSizeVar; + + pfile_in_zip_read_info->stream.avail_in = (uInt)0; + + s->pfile_in_zip_read = pfile_in_zip_read_info; + s->encrypted = 0; + +# ifndef NOUNCRYPT + if (password != NULL) + { + int i; + s->pcrc_32_tab = get_crc_table(); + init_keys(password,s->keys,s->pcrc_32_tab); + if (ZSEEK64(s->z_filefunc, s->filestream, + s->pfile_in_zip_read->pos_in_zipfile + + s->pfile_in_zip_read->byte_before_the_zipfile, + SEEK_SET)!=0) + return UNZ_INTERNALERROR; + if(ZREAD64(s->z_filefunc, s->filestream,source, 12)<12) + return UNZ_INTERNALERROR; + + for (i = 0; i<12; i++) + zdecode(s->keys,s->pcrc_32_tab,source[i]); + + s->pfile_in_zip_read->pos_in_zipfile+=12; + s->pfile_in_zip_read->rest_read_compressed-=12; + s->encrypted=1; + } +# endif + + + return UNZ_OK; +} + +extern int ZEXPORT unzOpenCurrentFile (unzFile file) +{ + return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL); +} + +extern int ZEXPORT unzOpenCurrentFilePassword (unzFile file, const char* password) +{ + return unzOpenCurrentFile3(file, NULL, NULL, 0, password); +} + +extern int ZEXPORT unzOpenCurrentFile2 (unzFile file, int* method, int* level, int raw) +{ + return unzOpenCurrentFile3(file, method, level, raw, NULL); +} + +/** Addition for GDAL : START */ + +extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64( unzFile file) +{ + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + s=(unz64_s*)file; + if (file==NULL) + return 0; //UNZ_PARAMERROR; + pfile_in_zip_read_info=s->pfile_in_zip_read; + if (pfile_in_zip_read_info==NULL) + return 0; //UNZ_PARAMERROR; + return pfile_in_zip_read_info->pos_in_zipfile + + pfile_in_zip_read_info->byte_before_the_zipfile; +} + +/** Addition for GDAL : END */ + +/* + Read bytes from the current file. + buf contain buffer where data must be copied + len the size of buf. + + return the number of byte copied if somes bytes are copied + return 0 if the end of file was reached + return <0 with error code if there is an error + (UNZ_ERRNO for IO error, or zLib error for uncompress error) +*/ +extern int ZEXPORT unzReadCurrentFile (unzFile file, voidp buf, unsigned len) +{ + int err=UNZ_OK; + uInt iRead = 0; + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + + if (pfile_in_zip_read_info->read_buffer == NULL) + return UNZ_END_OF_LIST_OF_FILE; + if (len==0) + return 0; + + pfile_in_zip_read_info->stream.next_out = (Bytef*)buf; + + pfile_in_zip_read_info->stream.avail_out = (uInt)len; + + if ((len>pfile_in_zip_read_info->rest_read_uncompressed) && + (!(pfile_in_zip_read_info->raw))) + pfile_in_zip_read_info->stream.avail_out = + (uInt)pfile_in_zip_read_info->rest_read_uncompressed; + + if ((len>pfile_in_zip_read_info->rest_read_compressed+ + pfile_in_zip_read_info->stream.avail_in) && + (pfile_in_zip_read_info->raw)) + pfile_in_zip_read_info->stream.avail_out = + (uInt)pfile_in_zip_read_info->rest_read_compressed+ + pfile_in_zip_read_info->stream.avail_in; + + while (pfile_in_zip_read_info->stream.avail_out>0) + { + if ((pfile_in_zip_read_info->stream.avail_in==0) && + (pfile_in_zip_read_info->rest_read_compressed>0)) + { + uInt uReadThis = UNZ_BUFSIZE; + if (pfile_in_zip_read_info->rest_read_compressedrest_read_compressed; + if (uReadThis == 0) + return UNZ_EOF; + if (ZSEEK64(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + pfile_in_zip_read_info->pos_in_zipfile + + pfile_in_zip_read_info->byte_before_the_zipfile, + ZLIB_FILEFUNC_SEEK_SET)!=0) + return UNZ_ERRNO; + if (ZREAD64(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + pfile_in_zip_read_info->read_buffer, + uReadThis)!=uReadThis) + return UNZ_ERRNO; + + +# ifndef NOUNCRYPT + if(s->encrypted) + { + uInt i; + for(i=0;iread_buffer[i] = + zdecode(s->keys,s->pcrc_32_tab, + pfile_in_zip_read_info->read_buffer[i]); + } +# endif + + + pfile_in_zip_read_info->pos_in_zipfile += uReadThis; + + pfile_in_zip_read_info->rest_read_compressed-=uReadThis; + + pfile_in_zip_read_info->stream.next_in = + (Bytef*)pfile_in_zip_read_info->read_buffer; + pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis; + } + + if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw)) + { + uInt uDoCopy,i ; + + if ((pfile_in_zip_read_info->stream.avail_in == 0) && + (pfile_in_zip_read_info->rest_read_compressed == 0)) + return (iRead==0) ? UNZ_EOF : iRead; + + if (pfile_in_zip_read_info->stream.avail_out < + pfile_in_zip_read_info->stream.avail_in) + uDoCopy = pfile_in_zip_read_info->stream.avail_out ; + else + uDoCopy = pfile_in_zip_read_info->stream.avail_in ; + + for (i=0;istream.next_out+i) = + *(pfile_in_zip_read_info->stream.next_in+i); + + pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uDoCopy; + + pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32, + pfile_in_zip_read_info->stream.next_out, + uDoCopy); + pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy; + pfile_in_zip_read_info->stream.avail_in -= uDoCopy; + pfile_in_zip_read_info->stream.avail_out -= uDoCopy; + pfile_in_zip_read_info->stream.next_out += uDoCopy; + pfile_in_zip_read_info->stream.next_in += uDoCopy; + pfile_in_zip_read_info->stream.total_out += uDoCopy; + iRead += uDoCopy; + } + else if (pfile_in_zip_read_info->compression_method==Z_BZIP2ED) + { +#ifdef HAVE_BZIP2 + uLong uTotalOutBefore,uTotalOutAfter; + const Bytef *bufBefore; + uLong uOutThis; + + pfile_in_zip_read_info->bstream.next_in = (char*)pfile_in_zip_read_info->stream.next_in; + pfile_in_zip_read_info->bstream.avail_in = pfile_in_zip_read_info->stream.avail_in; + pfile_in_zip_read_info->bstream.total_in_lo32 = pfile_in_zip_read_info->stream.total_in; + pfile_in_zip_read_info->bstream.total_in_hi32 = 0; + pfile_in_zip_read_info->bstream.next_out = (char*)pfile_in_zip_read_info->stream.next_out; + pfile_in_zip_read_info->bstream.avail_out = pfile_in_zip_read_info->stream.avail_out; + pfile_in_zip_read_info->bstream.total_out_lo32 = pfile_in_zip_read_info->stream.total_out; + pfile_in_zip_read_info->bstream.total_out_hi32 = 0; + + uTotalOutBefore = pfile_in_zip_read_info->bstream.total_out_lo32; + bufBefore = (const Bytef *)pfile_in_zip_read_info->bstream.next_out; + + err=BZ2_bzDecompress(&pfile_in_zip_read_info->bstream); + + uTotalOutAfter = pfile_in_zip_read_info->bstream.total_out_lo32; + uOutThis = uTotalOutAfter-uTotalOutBefore; + + pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis; + + pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,bufBefore, (uInt)(uOutThis)); + pfile_in_zip_read_info->rest_read_uncompressed -= uOutThis; + iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); + + pfile_in_zip_read_info->stream.next_in = (Bytef*)pfile_in_zip_read_info->bstream.next_in; + pfile_in_zip_read_info->stream.avail_in = pfile_in_zip_read_info->bstream.avail_in; + pfile_in_zip_read_info->stream.total_in = pfile_in_zip_read_info->bstream.total_in_lo32; + pfile_in_zip_read_info->stream.next_out = (Bytef*)pfile_in_zip_read_info->bstream.next_out; + pfile_in_zip_read_info->stream.avail_out = pfile_in_zip_read_info->bstream.avail_out; + pfile_in_zip_read_info->stream.total_out = pfile_in_zip_read_info->bstream.total_out_lo32; + + if (err==BZ_STREAM_END) + return (iRead==0) ? UNZ_EOF : iRead; + if (err!=BZ_OK) + break; +#endif + } // end Z_BZIP2ED + else + { + ZPOS64_T uTotalOutBefore,uTotalOutAfter; + const Bytef *bufBefore; + ZPOS64_T uOutThis; + int flush=Z_SYNC_FLUSH; + + uTotalOutBefore = pfile_in_zip_read_info->stream.total_out; + bufBefore = pfile_in_zip_read_info->stream.next_out; + + /* + if ((pfile_in_zip_read_info->rest_read_uncompressed == + pfile_in_zip_read_info->stream.avail_out) && + (pfile_in_zip_read_info->rest_read_compressed == 0)) + flush = Z_FINISH; + */ + err=inflate(&pfile_in_zip_read_info->stream,flush); + + if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL)) + err = Z_DATA_ERROR; + + uTotalOutAfter = pfile_in_zip_read_info->stream.total_out; + uOutThis = uTotalOutAfter-uTotalOutBefore; + + pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis; + + pfile_in_zip_read_info->crc32 = + crc32(pfile_in_zip_read_info->crc32,bufBefore, + (uInt)(uOutThis)); + + pfile_in_zip_read_info->rest_read_uncompressed -= + uOutThis; + + iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); + + if (err==Z_STREAM_END) + return (iRead==0) ? UNZ_EOF : iRead; + if (err!=Z_OK) + break; + } + } + + if (err==Z_OK) + return iRead; + return err; +} + + +/* + Give the current position in uncompressed data +*/ +extern z_off_t ZEXPORT unztell (unzFile file) +{ + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + return (z_off_t)pfile_in_zip_read_info->stream.total_out; +} + +extern ZPOS64_T ZEXPORT unztell64 (unzFile file) +{ + + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return (ZPOS64_T)-1; + s=(unz64_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return (ZPOS64_T)-1; + + return pfile_in_zip_read_info->total_out_64; +} + + +/* + return 1 if the end of file was reached, 0 elsewhere +*/ +extern int ZEXPORT unzeof (unzFile file) +{ + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + if (pfile_in_zip_read_info->rest_read_uncompressed == 0) + return 1; + else + return 0; +} + + + +/* +Read extra field from the current file (opened by unzOpenCurrentFile) +This is the local-header version of the extra field (sometimes, there is +more info in the local-header version than in the central-header) + + if buf==NULL, it return the size of the local extra field that can be read + + if buf!=NULL, len is the size of the buffer, the extra header is copied in + buf. + the return value is the number of bytes copied in buf, or (if <0) + the error code +*/ +extern int ZEXPORT unzGetLocalExtrafield (unzFile file, voidp buf, unsigned len) +{ + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + uInt read_now; + ZPOS64_T size_to_read; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + size_to_read = (pfile_in_zip_read_info->size_local_extrafield - + pfile_in_zip_read_info->pos_local_extrafield); + + if (buf==NULL) + return (int)size_to_read; + + if (len>size_to_read) + read_now = (uInt)size_to_read; + else + read_now = (uInt)len ; + + if (read_now==0) + return 0; + + if (ZSEEK64(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + pfile_in_zip_read_info->offset_local_extrafield + + pfile_in_zip_read_info->pos_local_extrafield, + ZLIB_FILEFUNC_SEEK_SET)!=0) + return UNZ_ERRNO; + + if (ZREAD64(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + buf,read_now)!=read_now) + return UNZ_ERRNO; + + return (int)read_now; +} + +/* + Close the file in zip opened with unzOpenCurrentFile + Return UNZ_CRCERROR if all the file was read but the CRC is not good +*/ +extern int ZEXPORT unzCloseCurrentFile (unzFile file) +{ + int err=UNZ_OK; + + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + + if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) && + (!pfile_in_zip_read_info->raw)) + { + if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait) + err=UNZ_CRCERROR; + } + + + TRYFREE(pfile_in_zip_read_info->read_buffer); + pfile_in_zip_read_info->read_buffer = NULL; + if (pfile_in_zip_read_info->stream_initialised == Z_DEFLATED) + inflateEnd(&pfile_in_zip_read_info->stream); +#ifdef HAVE_BZIP2 + else if (pfile_in_zip_read_info->stream_initialised == Z_BZIP2ED) + BZ2_bzDecompressEnd(&pfile_in_zip_read_info->bstream); +#endif + + + pfile_in_zip_read_info->stream_initialised = 0; + TRYFREE(pfile_in_zip_read_info); + + s->pfile_in_zip_read=NULL; + + return err; +} + + +/* + Get the global comment string of the ZipFile, in the szComment buffer. + uSizeBuf is the size of the szComment buffer. + return the number of byte copied or an error code <0 +*/ +extern int ZEXPORT unzGetGlobalComment (unzFile file, char * szComment, uLong uSizeBuf) +{ + unz64_s* s; + uLong uReadThis ; + if (file==NULL) + return (int)UNZ_PARAMERROR; + s=(unz64_s*)file; + + uReadThis = uSizeBuf; + if (uReadThis>s->gi.size_comment) + uReadThis = s->gi.size_comment; + + if (ZSEEK64(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0) + return UNZ_ERRNO; + + if (uReadThis>0) + { + *szComment='\0'; + if (ZREAD64(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis) + return UNZ_ERRNO; + } + + if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment)) + *(szComment+s->gi.size_comment)='\0'; + return (int)uReadThis; +} + +/* Additions by RX '2004 */ +extern ZPOS64_T ZEXPORT unzGetOffset64(unzFile file) +{ + unz64_s* s; + + if (file==NULL) + return 0; //UNZ_PARAMERROR; + s=(unz64_s*)file; + if (!s->current_file_ok) + return 0; + if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff) + if (s->num_file==s->gi.number_entry) + return 0; + return s->pos_in_central_dir; +} + +extern uLong ZEXPORT unzGetOffset (unzFile file) +{ + ZPOS64_T offset64; + + if (file==NULL) + return 0; //UNZ_PARAMERROR; + offset64 = unzGetOffset64(file); + return (uLong)offset64; +} + +extern int ZEXPORT unzSetOffset64(unzFile file, ZPOS64_T pos) +{ + unz64_s* s; + int err; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + + s->pos_in_central_dir = pos; + s->num_file = s->gi.number_entry; /* hack */ + err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + s->current_file_ok = (err == UNZ_OK); + return err; +} + +extern int ZEXPORT unzSetOffset (unzFile file, uLong pos) +{ + return unzSetOffset64(file,pos); +} diff --git a/lwnode/code/escargotshim/deps/minizip/unzip.h b/lwnode/code/escargotshim/deps/minizip/unzip.h new file mode 100644 index 0000000..2104e39 --- /dev/null +++ b/lwnode/code/escargotshim/deps/minizip/unzip.h @@ -0,0 +1,437 @@ +/* unzip.h -- IO for uncompress .zip files using zlib + Version 1.1, February 14h, 2010 + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications of Unzip for Zip64 + Copyright (C) 2007-2008 Even Rouault + + Modifications for Zip64 support on both zip and unzip + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + + For more info read MiniZip_info.txt + + --------------------------------------------------------------------------------- + + Condition of use and distribution are the same than zlib : + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + --------------------------------------------------------------------------------- + + Changes + + See header of unzip64.c + +*/ + +#ifndef _unz64_H +#define _unz64_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _ZLIB_H +#include "zlib.h" +#endif + +#ifndef _ZLIBIOAPI_H +#include "ioapi.h" +#endif + +#ifdef HAVE_BZIP2 +#include "bzlib.h" +#endif + +#define Z_BZIP2ED 12 + +#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP) +/* like the STRICT of WIN32, we define a pointer that cannot be converted + from (void*) without cast */ +typedef struct TagunzFile__ { int unused; } unzFile__; +typedef unzFile__ *unzFile; +#else +typedef voidp unzFile; +#endif + + +#define UNZ_OK (0) +#define UNZ_END_OF_LIST_OF_FILE (-100) +#define UNZ_ERRNO (Z_ERRNO) +#define UNZ_EOF (0) +#define UNZ_PARAMERROR (-102) +#define UNZ_BADZIPFILE (-103) +#define UNZ_INTERNALERROR (-104) +#define UNZ_CRCERROR (-105) + +/* tm_unz contain date/time info */ +typedef struct tm_unz_s +{ + uInt tm_sec; /* seconds after the minute - [0,59] */ + uInt tm_min; /* minutes after the hour - [0,59] */ + uInt tm_hour; /* hours since midnight - [0,23] */ + uInt tm_mday; /* day of the month - [1,31] */ + uInt tm_mon; /* months since January - [0,11] */ + uInt tm_year; /* years - [1980..2044] */ +} tm_unz; + +/* unz_global_info structure contain global data about the ZIPfile + These data comes from the end of central dir */ +typedef struct unz_global_info64_s +{ + ZPOS64_T number_entry; /* total number of entries in + the central dir on this disk */ + uLong size_comment; /* size of the global comment of the zipfile */ +} unz_global_info64; + +typedef struct unz_global_info_s +{ + uLong number_entry; /* total number of entries in + the central dir on this disk */ + uLong size_comment; /* size of the global comment of the zipfile */ +} unz_global_info; + +/* unz_file_info contain information about a file in the zipfile */ +typedef struct unz_file_info64_s +{ + uLong version; /* version made by 2 bytes */ + uLong version_needed; /* version needed to extract 2 bytes */ + uLong flag; /* general purpose bit flag 2 bytes */ + uLong compression_method; /* compression method 2 bytes */ + uLong dosDate; /* last mod file date in Dos fmt 4 bytes */ + uLong crc; /* crc-32 4 bytes */ + ZPOS64_T compressed_size; /* compressed size 8 bytes */ + ZPOS64_T uncompressed_size; /* uncompressed size 8 bytes */ + uLong size_filename; /* filename length 2 bytes */ + uLong size_file_extra; /* extra field length 2 bytes */ + uLong size_file_comment; /* file comment length 2 bytes */ + + uLong disk_num_start; /* disk number start 2 bytes */ + uLong internal_fa; /* internal file attributes 2 bytes */ + uLong external_fa; /* external file attributes 4 bytes */ + + tm_unz tmu_date; +} unz_file_info64; + +typedef struct unz_file_info_s +{ + uLong version; /* version made by 2 bytes */ + uLong version_needed; /* version needed to extract 2 bytes */ + uLong flag; /* general purpose bit flag 2 bytes */ + uLong compression_method; /* compression method 2 bytes */ + uLong dosDate; /* last mod file date in Dos fmt 4 bytes */ + uLong crc; /* crc-32 4 bytes */ + uLong compressed_size; /* compressed size 4 bytes */ + uLong uncompressed_size; /* uncompressed size 4 bytes */ + uLong size_filename; /* filename length 2 bytes */ + uLong size_file_extra; /* extra field length 2 bytes */ + uLong size_file_comment; /* file comment length 2 bytes */ + + uLong disk_num_start; /* disk number start 2 bytes */ + uLong internal_fa; /* internal file attributes 2 bytes */ + uLong external_fa; /* external file attributes 4 bytes */ + + tm_unz tmu_date; +} unz_file_info; + +extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1, + const char* fileName2, + int iCaseSensitivity)); +/* + Compare two filename (fileName1,fileName2). + If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) + If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi + or strcasecmp) + If iCaseSenisivity = 0, case sensitivity is defaut of your operating system + (like 1 on Unix, 2 on Windows) +*/ + + +extern unzFile ZEXPORT unzOpen OF((const char *path)); +extern unzFile ZEXPORT unzOpen64 OF((const void *path)); +/* + Open a Zip file. path contain the full pathname (by example, + on a Windows XP computer "c:\\zlib\\zlib113.zip" or on an Unix computer + "zlib/zlib113.zip". + If the zipfile cannot be opened (file don't exist or in not valid), the + return value is NULL. + Else, the return value is a unzFile Handle, usable with other function + of this unzip package. + the "64" function take a const void* pointer, because the path is just the + value passed to the open64_file_func callback. + Under Windows, if UNICODE is defined, using fill_fopen64_filefunc, the path + is a pointer to a wide unicode string (LPCTSTR is LPCWSTR), so const char* + does not describe the reality +*/ + + +extern unzFile ZEXPORT unzOpen2 OF((const char *path, + zlib_filefunc_def* pzlib_filefunc_def)); +/* + Open a Zip file, like unzOpen, but provide a set of file low level API + for read/write the zip file (see ioapi.h) +*/ + +extern unzFile ZEXPORT unzOpen2_64 OF((const void *path, + zlib_filefunc64_def* pzlib_filefunc_def)); +/* + Open a Zip file, like unz64Open, but provide a set of file low level API + for read/write the zip file (see ioapi.h) +*/ + +extern int ZEXPORT unzClose OF((unzFile file)); +/* + Close a ZipFile opened with unzOpen. + If there is files inside the .Zip opened with unzOpenCurrentFile (see later), + these files MUST be closed with unzCloseCurrentFile before call unzClose. + return UNZ_OK if there is no problem. */ + +extern int ZEXPORT unzGetGlobalInfo OF((unzFile file, + unz_global_info *pglobal_info)); + +extern int ZEXPORT unzGetGlobalInfo64 OF((unzFile file, + unz_global_info64 *pglobal_info)); +/* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. */ + + +extern int ZEXPORT unzGetGlobalComment OF((unzFile file, + char *szComment, + uLong uSizeBuf)); +/* + Get the global comment string of the ZipFile, in the szComment buffer. + uSizeBuf is the size of the szComment buffer. + return the number of byte copied or an error code <0 +*/ + + +/***************************************************************************/ +/* Unzip package allow you browse the directory of the zipfile */ + +extern int ZEXPORT unzGoToFirstFile OF((unzFile file)); +/* + Set the current file of the zipfile to the first file. + return UNZ_OK if there is no problem +*/ + +extern int ZEXPORT unzGoToNextFile OF((unzFile file)); +/* + Set the current file of the zipfile to the next file. + return UNZ_OK if there is no problem + return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. +*/ + +extern int ZEXPORT unzLocateFile OF((unzFile file, + const char *szFileName, + int iCaseSensitivity)); +/* + Try locate the file szFileName in the zipfile. + For the iCaseSensitivity signification, see unzStringFileNameCompare + + return value : + UNZ_OK if the file is found. It becomes the current file. + UNZ_END_OF_LIST_OF_FILE if the file is not found +*/ + + +/* ****************************************** */ +/* Ryan supplied functions */ +/* unz_file_info contain information about a file in the zipfile */ +typedef struct unz_file_pos_s +{ + uLong pos_in_zip_directory; /* offset in zip file directory */ + uLong num_of_file; /* # of file */ +} unz_file_pos; + +extern int ZEXPORT unzGetFilePos( + unzFile file, + unz_file_pos* file_pos); + +extern int ZEXPORT unzGoToFilePos( + unzFile file, + unz_file_pos* file_pos); + +typedef struct unz64_file_pos_s +{ + ZPOS64_T pos_in_zip_directory; /* offset in zip file directory */ + ZPOS64_T num_of_file; /* # of file */ +} unz64_file_pos; + +extern int ZEXPORT unzGetFilePos64( + unzFile file, + unz64_file_pos* file_pos); + +extern int ZEXPORT unzGoToFilePos64( + unzFile file, + const unz64_file_pos* file_pos); + +/* ****************************************** */ + +extern int ZEXPORT unzGetCurrentFileInfo64 OF((unzFile file, + unz_file_info64 *pfile_info, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize)); + +extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file, + unz_file_info *pfile_info, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize)); +/* + Get Info about the current file + if pfile_info!=NULL, the *pfile_info structure will contain somes info about + the current file + if szFileName!=NULL, the filemane string will be copied in szFileName + (fileNameBufferSize is the size of the buffer) + if extraField!=NULL, the extra field information will be copied in extraField + (extraFieldBufferSize is the size of the buffer). + This is the Central-header version of the extra field + if szComment!=NULL, the comment string of the file will be copied in szComment + (commentBufferSize is the size of the buffer) +*/ + + +/** Addition for GDAL : START */ + +extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64 OF((unzFile file)); + +/** Addition for GDAL : END */ + + +/***************************************************************************/ +/* for reading the content of the current zipfile, you can open it, read data + from it, and close it (you can close it before reading all the file) + */ + +extern int ZEXPORT unzOpenCurrentFile OF((unzFile file)); +/* + Open for reading data the current file in the zipfile. + If there is no error, the return value is UNZ_OK. +*/ + +extern int ZEXPORT unzOpenCurrentFilePassword OF((unzFile file, + const char* password)); +/* + Open for reading data the current file in the zipfile. + password is a crypting password + If there is no error, the return value is UNZ_OK. +*/ + +extern int ZEXPORT unzOpenCurrentFile2 OF((unzFile file, + int* method, + int* level, + int raw)); +/* + Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) + if raw==1 + *method will receive method of compression, *level will receive level of + compression + note : you can set level parameter as NULL (if you did not want known level, + but you CANNOT set method parameter as NULL +*/ + +extern int ZEXPORT unzOpenCurrentFile3 OF((unzFile file, + int* method, + int* level, + int raw, + const char* password)); +/* + Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) + if raw==1 + *method will receive method of compression, *level will receive level of + compression + note : you can set level parameter as NULL (if you did not want known level, + but you CANNOT set method parameter as NULL +*/ + + +extern int ZEXPORT unzCloseCurrentFile OF((unzFile file)); +/* + Close the file in zip opened with unzOpenCurrentFile + Return UNZ_CRCERROR if all the file was read but the CRC is not good +*/ + +extern int ZEXPORT unzReadCurrentFile OF((unzFile file, + voidp buf, + unsigned len)); +/* + Read bytes from the current file (opened by unzOpenCurrentFile) + buf contain buffer where data must be copied + len the size of buf. + + return the number of byte copied if somes bytes are copied + return 0 if the end of file was reached + return <0 with error code if there is an error + (UNZ_ERRNO for IO error, or zLib error for uncompress error) +*/ + +extern z_off_t ZEXPORT unztell OF((unzFile file)); + +extern ZPOS64_T ZEXPORT unztell64 OF((unzFile file)); +/* + Give the current position in uncompressed data +*/ + +extern int ZEXPORT unzeof OF((unzFile file)); +/* + return 1 if the end of file was reached, 0 elsewhere +*/ + +extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file, + voidp buf, + unsigned len)); +/* + Read extra field from the current file (opened by unzOpenCurrentFile) + This is the local-header version of the extra field (sometimes, there is + more info in the local-header version than in the central-header) + + if buf==NULL, it return the size of the local extra field + + if buf!=NULL, len is the size of the buffer, the extra header is copied in + buf. + the return value is the number of bytes copied in buf, or (if <0) + the error code +*/ + +/***************************************************************************/ + +/* Get the current file offset */ +extern ZPOS64_T ZEXPORT unzGetOffset64 (unzFile file); +extern uLong ZEXPORT unzGetOffset (unzFile file); + +/* Set the current file offset */ +extern int ZEXPORT unzSetOffset64 (unzFile file, ZPOS64_T pos); +extern int ZEXPORT unzSetOffset (unzFile file, uLong pos); + + + +#ifdef __cplusplus +} +#endif + +#endif /* _unz64_H */ diff --git a/lwnode/code/escargotshim/escargotshim.gyp b/lwnode/code/escargotshim/escargotshim.gyp index 6d7c967..5392388 100755 --- a/lwnode/code/escargotshim/escargotshim.gyp +++ b/lwnode/code/escargotshim/escargotshim.gyp @@ -76,12 +76,18 @@ ], 'include_dirs': [ 'src/api/utils/logger', + 'src/api/utils', 'include/lwnode', 'include', '.', ], 'cflags_cc!': ['-fno-exceptions'], 'cflags_cc': ['-fexceptions'], + 'conditions': [ + ['enable_external_builtin_scripts == "true"', { + 'defines': ['LWNODE_USE_EXTERNAL_BUILTIN_SCRIPTS'], + }], + ], }, 'conditions': [ ['OS == "linux"', { diff --git a/lwnode/code/escargotshim/include/lwnode/lwnode.h b/lwnode/code/escargotshim/include/lwnode/lwnode.h index d196252..98a4b60 100644 --- a/lwnode/code/escargotshim/include/lwnode/lwnode.h +++ b/lwnode/code/escargotshim/include/lwnode/lwnode.h @@ -26,6 +26,12 @@ void InitializeProcessMethods(v8::Local target, bool dumpSelfMemorySnapshot(); +class MessageLoop { + public: + // this callback should be called right before polling I/O events + static void OnPrepare(v8::Isolate* isolate); +}; + class Utils { public: // should return string buffer @@ -38,17 +44,20 @@ class Utils { const char* path() { return path_; } size_t preloadedDataLength() { return preloadedDataLength_; } + bool isOneByteString() { return isOneByteString_; } static ReloadableSourceData* create(std::string sourcePath, void* preloadedData, - size_t preloadedDataLength); + size_t preloadedDataLength, + bool isOneByteString); private: char* path_{nullptr}; size_t preloadedDataLength_{0}; + bool isOneByteString_{false}; ReloadableSourceData() = default; }; - static v8::MaybeLocal NewReloadableStringFromOneByte( + static v8::MaybeLocal NewReloadableString( v8::Isolate* isolate, ReloadableSourceData* data, LoadCallback loadCallback, diff --git a/lwnode/code/escargotshim/src/api-data.cc b/lwnode/code/escargotshim/src/api-data.cc index e3f9d89..fae9c88 100644 --- a/lwnode/code/escargotshim/src/api-data.cc +++ b/lwnode/code/escargotshim/src/api-data.cc @@ -1609,15 +1609,7 @@ Local v8::Object::CreationContext() { return Local(); } - auto globalObjectData = - ObjectRefHelper::getExtraData(esVal.get()->globalObject()) - ->asGlobalObjectData(); - - LWNODE_CHECK(globalObjectData->internalFieldCount() == - GlobalObjectData::kInternalFieldCount); - - auto lwCreationContext = reinterpret_cast( - globalObjectData->internalField(GlobalObjectData::kContextWrapSlot)); + auto lwCreationContext = ContextWrap::fromEscargot(esVal.get()); return v8::Local::New( lwIsolate->toV8(), diff --git a/lwnode/code/escargotshim/src/api-scripts.cc b/lwnode/code/escargotshim/src/api-scripts.cc index 97c07ef..a53bb7e 100644 --- a/lwnode/code/escargotshim/src/api-scripts.cc +++ b/lwnode/code/escargotshim/src/api-scripts.cc @@ -269,6 +269,12 @@ MaybeLocal ScriptCompiler::CompileUnboundInternal( esSource, esResourceName, source->GetResourceOptions().IsModule()); if (!result.isSuccessful()) { + Evaluator::EvaluatorResult r; + r.error = ExceptionHelper::createErrorObject( + esPureContext, result.parseErrorCode, result.parseErrorMessage); + + lwIsolate->SetPendingExceptionAndMessage(r.error.get(), r.stackTraceData); + lwIsolate->ReportPendingMessages(); return MaybeLocal(); } diff --git a/lwnode/code/escargotshim/src/api.h b/lwnode/code/escargotshim/src/api.h index 6bca167..f26624f 100644 --- a/lwnode/code/escargotshim/src/api.h +++ b/lwnode/code/escargotshim/src/api.h @@ -39,7 +39,7 @@ #include "api/module.h" #include "api/object.h" #include "api/serializer.h" -#include "api/utils/string.h" +#include "api/utils/string-util.h" namespace i = v8::internal; diff --git a/lwnode/code/escargotshim/src/api/context.cc b/lwnode/code/escargotshim/src/api/context.cc index da85006..fc576a5 100644 --- a/lwnode/code/escargotshim/src/api/context.cc +++ b/lwnode/code/escargotshim/src/api/context.cc @@ -32,8 +32,8 @@ static void evalJavaScript(ContextRef* context, ScriptParserRef::InitializeScriptResult scriptResult = context->scriptParser()->initializeScript( StringRef::createExternalFromASCII(buffer, bufferSize), - StringRef::createFromASCII(name, - strnlen(name, v8::String::kMaxLength))); + StringRef::createFromUTF8(name, + strnlen(name, v8::String::kMaxLength))); LWNODE_CHECK_MSG(scriptResult.isSuccessful(), "Cannot parser %s: %s", name, @@ -99,6 +99,19 @@ ContextWrap* ContextWrap::New(IsolateWrap* isolate) { return new ContextWrap(isolate); } +ContextWrap* ContextWrap::fromEscargot(Escargot::ContextRef* esContext) { + auto globalObjectData = + ObjectRefHelper::getExtraData(esContext->globalObject()) + ->asGlobalObjectData(); + + LWNODE_CHECK(globalObjectData->internalFieldCount() == + GlobalObjectData::kInternalFieldCount); + + auto lwCreationContext = reinterpret_cast( + globalObjectData->internalField(GlobalObjectData::kContextWrapSlot)); + return lwCreationContext; +} + void ContextWrap::Enter() { isolate_->Enter(); isolate_->pushContext(this); diff --git a/lwnode/code/escargotshim/src/api/context.h b/lwnode/code/escargotshim/src/api/context.h index 81ce211..4edfa7c 100644 --- a/lwnode/code/escargotshim/src/api/context.h +++ b/lwnode/code/escargotshim/src/api/context.h @@ -29,6 +29,7 @@ typedef GCUnorderedMap EmbedderDataMap; class ContextWrap : public ValueWrap { public: static ContextWrap* New(IsolateWrap* isolate); + static ContextWrap* fromEscargot(Escargot::ContextRef* context); void Enter(); void Exit(); diff --git a/lwnode/code/escargotshim/src/api/engine.cc b/lwnode/code/escargotshim/src/api/engine.cc index 7861697..d3a6d05 100644 --- a/lwnode/code/escargotshim/src/api/engine.cc +++ b/lwnode/code/escargotshim/src/api/engine.cc @@ -19,7 +19,7 @@ #include #include "handle.h" #include "utils/misc.h" -#include "utils/string.h" +#include "utils/string-util.h" using namespace Escargot; diff --git a/lwnode/code/escargotshim/src/api/es-helper.cc b/lwnode/code/escargotshim/src/api/es-helper.cc index bf98eb1..259edb1 100755 --- a/lwnode/code/escargotshim/src/api/es-helper.cc +++ b/lwnode/code/escargotshim/src/api/es-helper.cc @@ -19,7 +19,7 @@ #include "extra-data.h" #include "isolate.h" #include "utils/misc.h" -#include "utils/string.h" +#include "utils/string-util.h" #include diff --git a/lwnode/code/escargotshim/src/api/isolate.cc b/lwnode/code/escargotshim/src/api/isolate.cc index f7f30d1..a665c2f 100755 --- a/lwnode/code/escargotshim/src/api/isolate.cc +++ b/lwnode/code/escargotshim/src/api/isolate.cc @@ -216,8 +216,8 @@ IsolateWrap::IsolateWrap() { globalHandles_ = new GlobalHandles(toV8()); privateValuesSymbol_ = PersistentRefHolder( - SymbolRef::create(StringRef::createFromASCII(PRIVATE_VALUES.data(), - PRIVATE_VALUES.length()))); + SymbolRef::create(StringRef::createFromUTF8(PRIVATE_VALUES.data(), + PRIVATE_VALUES.length()))); // NOTE: check lock_gc_release(); is needed (and where) // lock_gc_release(); diff --git a/lwnode/code/escargotshim/src/api/stack-trace.cc b/lwnode/code/escargotshim/src/api/stack-trace.cc index d48642f..c62de4b 100644 --- a/lwnode/code/escargotshim/src/api/stack-trace.cc +++ b/lwnode/code/escargotshim/src/api/stack-trace.cc @@ -190,7 +190,7 @@ static void setCallSitePrototype( LWNODE_CHECK(r.isSuccessful()); otpl->set( - StringRef::createFromASCII(name, length), r.result, false, false, true); + StringRef::createFromUTF8(name, length), r.result, false, false, true); } static void injectSitePrototype(ContextRef* context, ObjectTemplateRef* otpl) { @@ -280,7 +280,7 @@ static void injectSitePrototype(ContextRef* context, ObjectTemplateRef* otpl) { << data->src()->toStdUTF8String() << ":" << data->loc().line << ":" << data->loc().column << ")"; auto string = stream.str(); - return StringRef::createFromASCII(string.data(), string.length()); + return StringRef::createFromUTF8(string.data(), string.length()); }); } diff --git a/lwnode/code/escargotshim/src/api/utils.h b/lwnode/code/escargotshim/src/api/utils.h index fd24174..25d53b2 100644 --- a/lwnode/code/escargotshim/src/api/utils.h +++ b/lwnode/code/escargotshim/src/api/utils.h @@ -21,4 +21,4 @@ #include "utils/conversions-inl.h" #include "utils/gc.h" #include "utils/misc.h" -#include "utils/string.h" +#include "utils/string-util.h" diff --git a/lwnode/code/escargotshim/src/api/utils/string.h b/lwnode/code/escargotshim/src/api/utils/string-util.h similarity index 100% rename from lwnode/code/escargotshim/src/api/utils/string.h rename to lwnode/code/escargotshim/src/api/utils/string-util.h diff --git a/lwnode/code/escargotshim/src/lwnode.cc b/lwnode/code/escargotshim/src/lwnode.cc index 3c69a6d..647b0c6 100644 --- a/lwnode/code/escargotshim/src/lwnode.cc +++ b/lwnode/code/escargotshim/src/lwnode.cc @@ -16,9 +16,12 @@ #include "lwnode/lwnode.h" #include +#include // for malloc_trim #include #include #include "api.h" +#include "api/context.h" +#include "api/es-helper.h" #include "api/isolate.h" #include "api/utils/misc.h" #include "api/utils/smaps.h" @@ -57,7 +60,7 @@ static void SetMethod(ContextRef* context, return ValueRef::createUndefined(); }, target, - StringRef::createFromASCII(name.c_str(), name.length()), + StringRef::createFromUTF8(name.c_str(), name.length()), nativeFunction); } @@ -132,7 +135,7 @@ static ValueRef* MemSnapshot(ExecutionStateRef* state, auto outputPath = createDumpFilePath(); auto& smaps = getSelfSmaps(); if (dumpMemorySnapshot(outputPath, smaps)) { - return StringRef::createFromASCII(outputPath.c_str(), outputPath.length()); + return StringRef::createFromUTF8(outputPath.c_str(), outputPath.length()); } return ValueRef::createUndefined(); }; @@ -152,7 +155,10 @@ void InitializeProcessMethods(Local target, Local context) { } Utils::ReloadableSourceData* Utils::ReloadableSourceData::create( - std::string sourcePath, void* preloadedData, size_t preloadedDataLength) { + std::string sourcePath, + void* preloadedData, + size_t preloadedDataLength, + bool isOneByteString) { auto data = new (Memory::gcMalloc(sizeof(ReloadableSourceData))) ReloadableSourceData(); @@ -162,15 +168,15 @@ Utils::ReloadableSourceData* Utils::ReloadableSourceData::create( data->preloadedData = preloadedData; data->preloadedDataLength_ = preloadedDataLength; + data->isOneByteString_ = isOneByteString; return data; } -MaybeLocal Utils::NewReloadableStringFromOneByte( - Isolate* isolate, - ReloadableSourceData* data, - LoadCallback loadCallback, - UnloadCallback unloadCallback) { +MaybeLocal Utils::NewReloadableString(Isolate* isolate, + ReloadableSourceData* data, + LoadCallback loadCallback, + UnloadCallback unloadCallback) { MaybeLocal result; if (data->preloadedDataLength() == 0) { @@ -181,7 +187,7 @@ MaybeLocal Utils::NewReloadableStringFromOneByte( Escargot::StringRef* reloadableString = Escargot::StringRef::createReloadableString( IsolateWrap::fromV8(isolate)->vmInstance(), - true, + data->isOneByteString(), data->preloadedDataLength(), data, // data should be gc-managed. loadCallback, @@ -192,4 +198,19 @@ MaybeLocal Utils::NewReloadableStringFromOneByte( return result; } +static void IdleGC(v8::Isolate* isolate) { + LWNODE_LOG_INFO("IdleGC"); + IsolateWrap::fromV8(isolate)->vmInstance()->enterIdleMode(); + Escargot::Memory::gc(); + malloc_trim(0); +} + +void MessageLoop::OnPrepare(v8::Isolate* isolate) { + // @note escargot says: + // user can call 'enterIdleMode' many times without performance concern + + // @todo consider delayed-entering Idle GC + IdleGC(isolate); +} + } // namespace LWNode diff --git a/node.gyp b/node.gyp index 0de1fb4..49693ce 100644 --- a/node.gyp +++ b/node.gyp @@ -770,6 +770,33 @@ 'dependencies': [ '<(lwnode_jsengine_path)/escargotshim.gyp:escargotshim', ], + 'conditions': [ + ['enable_external_builtin_scripts=="true"', { + 'variables': { + 'archive_filename%': '<(node_core_target_name).dat' + }, + 'defines': [ + 'LWNODE_EXTERNAL_BUILTINS_FILENAME="<(archive_filename)"', + ], + 'dependencies': [ + '<(lwnode_jsengine_path)/deps/minizip/minizip.gyp:minizip', + ], + 'actions': [ + { + 'action_name': 'generate_builtins_archive', + 'inputs': ['<@(library_files)'], + 'outputs': ['<(PRODUCT_DIR)/<(archive_filename)'], + 'process_outputs_as_sources': 1, + 'action': [ + 'zip', + '-0', # no compression + '<(PRODUCT_DIR)/<(archive_filename)', + '<@(_inputs)', + ], + }, + ], + }], + ], }], [ 'openssl_default_cipher_list!=""', { 'defines': [ @@ -966,9 +993,18 @@ 'outputs': [ '<(SHARED_INTERMEDIATE_DIR)/node_javascript.cc', ], - 'action': [ - 'python', '<@(_inputs)', - '--target', '<@(_outputs)', + 'conditions': [ + ['lwnode=="true" and enable_external_builtin_scripts=="true"', { + 'action': [ + 'python', '<@(_inputs)', + '--reloadable', + '--target', '<@(_outputs)', + ]}, { + 'action': [ + 'python', '<@(_inputs)', + '--target', '<@(_outputs)', + ], + }] ], }, ], diff --git a/packaging/lwnode.spec b/packaging/lwnode.spec index 9f29476..c90cd5a 100644 --- a/packaging/lwnode.spec +++ b/packaging/lwnode.spec @@ -24,6 +24,7 @@ BuildRequires: cmake BuildRequires: make BuildRequires: python BuildRequires: ninja +BuildRequires: zip BuildRequires: pkgconfig(dlog) BuildRequires: pkgconfig(aul) BuildRequires: pkgconfig(capi-appfw-app-common) @@ -32,6 +33,8 @@ BuildRequires: pkgconfig(capi-system-system-settings) BuildRequires: pkgconfig(icu-i18n) BuildRequires: pkgconfig(icu-uc) BuildRequires: pkgconfig(glib-2.0) +BuildRequires: nghttp2-devel +BuildRequires: pkgconfig(libcares) %if (0%{?tizen_version_major} >= 6) BuildRequires: pkgconfig(openssl1.1) @@ -116,10 +119,15 @@ LDFLAGS+="-fsanitize=address" echo "Building:" %{target} +CFLAGS+=' -Os ' +CXXFLAGS+=' -Os ' + ./configure --tizen --without-npm \ --without-inspector --without-node-code-cache --without-node-snapshot \ - --with-intl none --shared-openssl --shared-zlib --dest-os linux --dest-cpu '%{tizen_arch}' \ - --ninja %{?extra_config} %{?lib_type_config} + --with-intl none --shared-openssl --shared-zlib --shared-cares --shared-nghttp2 \ + --dest-os linux --dest-cpu '%{tizen_arch}' \ + --ninja %{?extra_config} %{?external_script_config} %{?lib_type_config} + %if "%{node_engine}" == "escargot" && "%{lib_type}" == "shared" ninja -C %{target_src} %{target_lib} %endif @@ -144,6 +152,9 @@ cp %{target_src}/gen/escargot/libescargot.so %{buildroot}%{_libdir} # for devel files strip -v -g %{target_src}/%{target} cp %{target_src}/%{target} %{buildroot}%{_bindir} +%if "%{external_script_config}" == "--enable-external-builtin-scripts" +cp %{target_src}/%{target}.dat %{buildroot}%{_bindir} +%endif %clean rm ./*.list @@ -172,3 +183,6 @@ rm ./*.manifest %files devel %manifest packaging/%{name}.manifest %{_bindir}/%{target} +%if "%{external_script_config}" == "--enable-external-builtin-scripts" +%{_bindir}/%{target}.dat +%endif diff --git a/src/node_native_module.cc b/src/node_native_module.cc index 4c3633e..d687af4 100644 --- a/src/node_native_module.cc +++ b/src/node_native_module.cc @@ -1,6 +1,10 @@ #include "node_native_module.h" #include "util-inl.h" +#ifdef LWNODE_EXTERNAL_BUILTINS_FILENAME +#include "node_native_module_lwnode-inl.h" +#endif + namespace node { namespace native_module { @@ -202,6 +206,10 @@ static std::string OnDiskFileName(const char* id) { MaybeLocal NativeModuleLoader::LoadBuiltinModuleSource(Isolate* isolate, const char* id) { +#ifdef LWNODE_EXTERNAL_BUILTINS_FILENAME + return LoadExternalBuiltinSource(isolate, id); +#endif + #ifdef NODE_BUILTIN_MODULES_PATH std::string filename = OnDiskFileName(id); diff --git a/src/node_native_module.h b/src/node_native_module.h index 3be3f23..1639a70 100644 --- a/src/node_native_module.h +++ b/src/node_native_module.h @@ -39,6 +39,12 @@ class NativeModuleLoader { friend class NativeModuleEnv; friend class CodeCacheBuilder; + // @lwnode + inline bool IsOneByte(const char* id); + v8::MaybeLocal LoadExternalBuiltinSource( + v8::Isolate* isolate, const char* id); + // end of @lwnode + NativeModuleLoader(); static NativeModuleLoader* GetInstance(); diff --git a/src/node_native_module_lwnode-inl.h b/src/node_native_module_lwnode-inl.h new file mode 100644 index 0000000..e8268d1 --- /dev/null +++ b/src/node_native_module_lwnode-inl.h @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2021-present Samsung Electronics Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include "lwnode.h" +#include "node_native_module.h" +#include "trace.h" + +using namespace LWNode; + +namespace node { +namespace native_module { +using v8::Isolate; +using v8::Local; +using v8::MaybeLocal; +using v8::String; + +std::string getSelfProcPath() { + char path[PATH_MAX]; + ssize_t length = readlink("/proc/self/exe", path, PATH_MAX); + if (length < 0) { + ERROR_AND_ABORT("readlink fails"); + } + path[length] = '\0'; + return std::string(path); +} + +class ArchiveFileScope { + public: + ArchiveFileScope(const char* path) { file_ = unzOpen(path); } + ~ArchiveFileScope() { unzClose(file_); } + unzFile file() { return file_; } + + private: + unzFile file_{nullptr}; +}; + +bool readFileFromArchive(std::string filename, + char** buffer, + size_t* fileSize) { + DCHECK_NOT_NULL(buffer); + DCHECK_NOT_NULL(fileSize); + + static std::string s_externalBuiltinsPath; + if (s_externalBuiltinsPath.empty()) { + std::string executablePath = getSelfProcPath(); + executablePath = executablePath.substr(0, executablePath.rfind('/') + 1); + s_externalBuiltinsPath = executablePath + LWNODE_EXTERNAL_BUILTINS_FILENAME; + } + + ArchiveFileScope scope(s_externalBuiltinsPath.c_str()); + const unzFile file = scope.file(); + CHECK_NOT_NULL(file); + + if (unzGoToFirstFile(file) < 0) { + return false; + } + + bool isFileFound = false; + do { + unz_file_info fileInfo; + char currentFileName[PATH_MAX]; + + if (unzGetCurrentFileInfo(file, + &fileInfo, + currentFileName, + sizeof(currentFileName), + nullptr, + 0, + nullptr, + 0) < 0) { + return false; + } + + if (filename.compare(currentFileName) == 0) { + isFileFound = true; + + if (unzOpenCurrentFile(file) < 0) { + return false; + } + + *fileSize = fileInfo.uncompressed_size; + *buffer = (char*)malloc(fileInfo.uncompressed_size); + + if (unzReadCurrentFile(file, *buffer, *fileSize) < 0) { + free(buffer); + buffer = nullptr; + return false; + } + unzCloseCurrentFile(file); + break; + } + + } while (unzGoToNextFile(file) != UNZ_END_OF_LIST_OF_FILE); + + return isFileFound; +} + +bool NativeModuleLoader::IsOneByte(const char* id) { + const auto& it = source_.find(id); + if (it == source_.end()) { + CHECK(false); + } + return it->second.is_one_byte(); +} + +static std::string OnArchiveFileName(const char* id) { + std::string filename; + if (strncmp(id, "internal/deps", strlen("internal/deps")) == 0) { + id += strlen("internal/"); + } else { + filename += "lib/"; + } + filename += id; + filename += ".js"; + return filename; +} + +MaybeLocal NativeModuleLoader::LoadExternalBuiltinSource( + Isolate* isolate, const char* id) { + std::string filename = OnArchiveFileName(id); + + size_t fileSize = 0; + char* buffer = nullptr; + if (readFileFromArchive(filename, &buffer, &fileSize) == false) { + ERROR_AND_ABORT("Failed to open builtins"); + return MaybeLocal(); + } + + struct Stat { + int loaded{0}; + int reloaded{0}; + }; + static Stat s_stat; + + bool is8BitString = true; + if (IsOneByte(id) == false) { + // FIXME: should be `is8BitString = false;` here + // "lib/internal/cli_table.js", "lib/internal/timers.js", + // "deps/node-inspect/lib/internal/inspect_repl.js", + // "deps/acorn/acorn/dist/acorn.js" + LWNODE_LOG_ERROR( + "FIXME: %s - createReloadableString fails to load uint16 string", id); + } + + auto data = Utils::ReloadableSourceData::create( + filename, buffer, fileSize, is8BitString); + + return Utils::NewReloadableString( + isolate, + data, + // Load-ReloadableSource + [](void* userData) -> void* { + auto data = reinterpret_cast(userData); + + LWNODE_LOG_INFO(" Load: %d (%d) %p %s (+%.2f kB)", + ++s_stat.loaded, + s_stat.reloaded, + data->preloadedData, + data->path(), + (float)data->preloadedDataLength() / 1024); + + if (data->preloadedData) { + auto buffer = data->preloadedData; + data->preloadedData = nullptr; + return buffer; // move memory ownership to js engine + } + + s_stat.reloaded++; + size_t fileSize = 0; + char* buffer = nullptr; + bool result = readFileFromArchive(data->path(), &buffer, &fileSize); + CHECK(result); + return buffer; + }, + // Unload-ReloadableSource + [](void* preloadedData, void* userData) -> void { + auto data = reinterpret_cast(userData); + + LWNODE_LOG_INFO("Unload: %d (%d) %p %s (-%.2f kB)", + --s_stat.loaded, + s_stat.reloaded, + preloadedData, + data->path(), + (float)data->preloadedDataLength() / 1024); + + if (data->preloadedData) { + free(data->preloadedData); + data->preloadedData = nullptr; + } + free(preloadedData); + }); +} + +} // namespace native_module +} // namespace node diff --git a/src/node_platform.cc b/src/node_platform.cc index 9f97bf1..a842e84 100644 --- a/src/node_platform.cc +++ b/src/node_platform.cc @@ -219,6 +219,13 @@ int WorkerThreadsTaskRunner::NumberOfWorkerThreads() const { return threads_.size(); } +#ifdef LWNODE +void PerIsolatePlatformData::PrepareTask(uv_prepare_t *handle) { + auto data = reinterpret_cast(handle->data); + LWNode::MessageLoop::OnPrepare(data->isolate_); +} +#endif + PerIsolatePlatformData::PerIsolatePlatformData( Isolate* isolate, uv_loop_t* loop) : isolate_(isolate), loop_(loop) { @@ -226,6 +233,14 @@ PerIsolatePlatformData::PerIsolatePlatformData( CHECK_EQ(0, uv_async_init(loop, flush_tasks_, FlushTasks)); flush_tasks_->data = static_cast(this); uv_unref(reinterpret_cast(flush_tasks_)); + +#if defined(LWNODE) && defined(LWNODE_EXTERNAL_BUILTINS_FILENAME) + prepare_task_ = new uv_prepare_t(); + uv_prepare_init(loop_, prepare_task_); + uv_prepare_start(prepare_task_, PrepareTask); + prepare_task_->data = static_cast(this); + uv_unref(reinterpret_cast(prepare_task_)); +#endif } std::shared_ptr @@ -329,6 +344,13 @@ void PerIsolatePlatformData::AddShutdownCallback(void (*callback)(void*), } void PerIsolatePlatformData::Shutdown() { +#ifdef LWNODE + if (prepare_task_) { + uv_close(reinterpret_cast(prepare_task_), nullptr); + prepare_task_ = nullptr; + } +#endif + if (flush_tasks_ == nullptr) return; diff --git a/src/node_platform.h b/src/node_platform.h index dc512dd..f3d24f8 100644 --- a/src/node_platform.h +++ b/src/node_platform.h @@ -106,6 +106,11 @@ class PerIsolatePlatformData : TaskQueue foreground_tasks_; TaskQueue foreground_delayed_tasks_; +//@lwnode + uv_prepare_t* prepare_task_ = nullptr; + static void PrepareTask(uv_prepare_t* handle); +//end of @lwnode + // Use a custom deleter because libuv needs to close the handle first. typedef std::unique_ptr DelayedTaskPointer; diff --git a/tools/js2c.py b/tools/js2c.py index 195e6a6..d2f5f1c 100755 --- a/tools/js2c.py +++ b/tools/js2c.py @@ -89,7 +89,7 @@ SLUGGER_RE =re.compile('[.\-/]') is_verbose = False -def GetDefinition(var, source, step=30): +def GetDefinition(var, source, is_reloadable_code=False, step=30): template = ONE_BYTE_STRING code_points = [ord(c) for c in source] if any(c > 127 for c in code_points): @@ -107,19 +107,26 @@ def GetDefinition(var, source, step=30): slices = [elements_s[i:i + step] for i in range(0, len(elements_s), step)] lines = [','.join(s) for s in slices] array_content = ',\n'.join(lines) - definition = template.format(var, array_content) + if is_reloadable_code == True: + definition = template.format(var, '') + else: + definition = template.format(var, array_content) return definition, len(code_points) -def AddModule(filename, definitions, initializers): +def AddModule(filename, definitions, initializers, is_reloadable_code=False): code = ReadFile(filename) name = NormalizeFileName(filename) slug = SLUGGER_RE.sub('_', name) var = slug + '_raw' - definition, size = GetDefinition(var, code) - initializer = INITIALIZER.format(name, var, size) - definitions.append(definition) + definition, size = GetDefinition(var, code, is_reloadable_code) + if is_reloadable_code == True: + initializer = INITIALIZER.format(name, var, 0) + definitions.append(definition) + else: + initializer = INITIALIZER.format(name, var, size) + definitions.append(definition) initializers.append(initializer) def NormalizeFileName(filename): @@ -133,13 +140,13 @@ def NormalizeFileName(filename): return os.path.splitext(filename)[0] -def JS2C(source_files, target): +def JS2C(source_files, target, is_reloadable_code=False): # Build source code lines definitions = [] initializers = [] for filename in source_files['.js']: - AddModule(filename, definitions, initializers) + AddModule(filename, definitions, initializers, is_reloadable_code) config_def, config_size = handle_config_gypi(source_files['config.gypi']) definitions.append(config_def) @@ -156,7 +163,7 @@ def handle_config_gypi(config_filename): # later on anyway, so get it out of the way now config = ReadFile(config_filename) config = jsonify(config) - config_def, config_size = GetDefinition(CONFIG_GYPI_ID, config) + config_def, config_size = GetDefinition(CONFIG_GYPI_ID, config, False) return config_def, config_size @@ -201,6 +208,11 @@ def main(): ) parser.add_argument('--target', help='output file') parser.add_argument('--verbose', action='store_true', help='output file') + # @lwnode --reloadable + parser.add_argument('--reloadable', + action='store_true', + default=False, + help='reloadable string') parser.add_argument('sources', nargs='*', help='input files') options = parser.parse_args() global is_verbose @@ -211,7 +223,7 @@ def main(): # Currently config.gypi is the only `.gypi` file allowed assert source_files['.gypi'] == ['config.gypi'] source_files['config.gypi'] = source_files.pop('.gypi')[0] - JS2C(source_files, options.target) + JS2C(source_files, options.target, options.reloadable) if __name__ == "__main__":