LWNode_Release_210917_1fb131f 89/264389/1 accepted/tizen/unified/20210917.060807 submit/tizen/20210917.003833
authorRyan Hyun Choi <ryan.choi@samsung.com>
Fri, 17 Sep 2021 00:32:00 +0000 (09:32 +0900)
committerRyan Hyun Choi <ryan.choi@samsung.com>
Fri, 17 Sep 2021 00:32:15 +0000 (09:32 +0900)
Change-Id: I3d363478c36160a38c24c97f776b3fe6770ed02c
Signed-off-by: Ryan Choi <ryan.choi@samsung.com>
112 files changed:
lwnode/code/escargotshim/common.gypi
lwnode/code/escargotshim/deps/escargot/build/target.cmake
lwnode/code/escargotshim/deps/escargot/src/Escargot.h
lwnode/code/escargotshim/deps/escargot/src/api/EscargotPublic.cpp
lwnode/code/escargotshim/deps/escargot/src/api/EscargotPublic.h
lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinArray.cpp
lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinArrayBuffer.cpp
lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinAsyncFromSyncIterator.cpp
lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinAsyncFunction.cpp
lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinAsyncGeneratorFunction.cpp
lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinAsyncIterator.cpp [deleted file]
lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinAtomics.cpp
lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinBigInt.cpp
lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinBoolean.cpp
lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinDataView.cpp
lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinDate.cpp
lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinError.cpp
lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinFinalizationRegistry.cpp
lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinFunction.cpp
lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinGeneratorFunction.cpp
lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinIntl.cpp
lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinIterator.cpp [deleted file]
lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinJSON.cpp
lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinMap.cpp
lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinMath.cpp
lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinNumber.cpp
lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinObject.cpp
lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinPromise.cpp
lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinProxy.cpp
lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinReflect.cpp
lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinRegExp.cpp
lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinSet.cpp
lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinSharedArrayBuffer.cpp
lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinString.cpp
lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinSymbol.cpp
lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinTypedArray.cpp
lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinWeakMap.cpp
lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinWeakRef.cpp
lwnode/code/escargotshim/deps/escargot/src/builtins/BuiltinWeakSet.cpp
lwnode/code/escargotshim/deps/escargot/src/interpreter/ByteCode.cpp
lwnode/code/escargotshim/deps/escargot/src/interpreter/ByteCode.h
lwnode/code/escargotshim/deps/escargot/src/interpreter/ByteCodeGenerator.cpp
lwnode/code/escargotshim/deps/escargot/src/interpreter/ByteCodeInterpreter.cpp
lwnode/code/escargotshim/deps/escargot/src/intl/Intl.cpp
lwnode/code/escargotshim/deps/escargot/src/intl/Intl.h
lwnode/code/escargotshim/deps/escargot/src/intl/IntlDateTimeFormat.cpp
lwnode/code/escargotshim/deps/escargot/src/intl/IntlDateTimeFormat.h
lwnode/code/escargotshim/deps/escargot/src/intl/IntlNumberFormat.cpp
lwnode/code/escargotshim/deps/escargot/src/parser/CodeBlock.h
lwnode/code/escargotshim/deps/escargot/src/parser/ast/ASTContext.h
lwnode/code/escargotshim/deps/escargot/src/parser/ast/ForInOfStatementNode.h
lwnode/code/escargotshim/deps/escargot/src/parser/ast/ReturnStatementNode.h
lwnode/code/escargotshim/deps/escargot/src/parser/ast/StatementNode.h
lwnode/code/escargotshim/deps/escargot/src/parser/esprima_cpp/esprima.cpp
lwnode/code/escargotshim/deps/escargot/src/runtime/ArrayObject.cpp
lwnode/code/escargotshim/deps/escargot/src/runtime/Context.cpp
lwnode/code/escargotshim/deps/escargot/src/runtime/EnvironmentRecord.h
lwnode/code/escargotshim/deps/escargot/src/runtime/ErrorObject.cpp
lwnode/code/escargotshim/deps/escargot/src/runtime/Global.cpp
lwnode/code/escargotshim/deps/escargot/src/runtime/Global.h
lwnode/code/escargotshim/deps/escargot/src/runtime/GlobalObject.cpp
lwnode/code/escargotshim/deps/escargot/src/runtime/GlobalObject.h
lwnode/code/escargotshim/deps/escargot/src/runtime/NumberObject.cpp
lwnode/code/escargotshim/deps/escargot/src/runtime/Object.cpp
lwnode/code/escargotshim/deps/escargot/src/runtime/Object.h
lwnode/code/escargotshim/deps/escargot/src/runtime/Platform.h
lwnode/code/escargotshim/deps/escargot/src/runtime/PointerValue.h
lwnode/code/escargotshim/deps/escargot/src/runtime/ProxyObject.cpp
lwnode/code/escargotshim/deps/escargot/src/runtime/ScriptArrowFunctionObject.cpp
lwnode/code/escargotshim/deps/escargot/src/runtime/ScriptAsyncFunctionObject.cpp
lwnode/code/escargotshim/deps/escargot/src/runtime/ScriptAsyncGeneratorFunctionObject.cpp
lwnode/code/escargotshim/deps/escargot/src/runtime/ScriptClassConstructorFunctionObject.cpp
lwnode/code/escargotshim/deps/escargot/src/runtime/ScriptGeneratorFunctionObject.cpp
lwnode/code/escargotshim/deps/escargot/src/runtime/ScriptVirtualArrowFunctionObject.cpp
lwnode/code/escargotshim/deps/escargot/src/runtime/StaticStrings.cpp
lwnode/code/escargotshim/deps/escargot/src/runtime/StaticStrings.h
lwnode/code/escargotshim/deps/escargot/src/shell/Shell.cpp
lwnode/code/escargotshim/deps/escargot/src/wasm/BuiltinWASM.cpp [moved from lwnode/code/escargotshim/deps/escargot/src/wasm/GlobalObjectBuiltinWASM.cpp with 96% similarity]
lwnode/code/escargotshim/deps/escargot/third_party/runtime_icu_binder/ICUPolyfill.h
lwnode/code/escargotshim/deps/escargot/third_party/runtime_icu_binder/RuntimeICUBinder.h
lwnode/code/escargotshim/deps/escargot/tools/debugger/tests/do_break_class.cmd [new file with mode: 0644]
lwnode/code/escargotshim/deps/escargot/tools/debugger/tests/do_break_class.expected [new file with mode: 0644]
lwnode/code/escargotshim/deps/escargot/tools/debugger/tests/do_step_class.cmd [new file with mode: 0644]
lwnode/code/escargotshim/deps/escargot/tools/debugger/tests/do_step_class.expected [new file with mode: 0644]
lwnode/code/escargotshim/deps/minizip/crypt.h [new file with mode: 0644]
lwnode/code/escargotshim/deps/minizip/ioapi.c [new file with mode: 0644]
lwnode/code/escargotshim/deps/minizip/ioapi.h [new file with mode: 0644]
lwnode/code/escargotshim/deps/minizip/minizip.gyp [new file with mode: 0755]
lwnode/code/escargotshim/deps/minizip/unzip.c [new file with mode: 0644]
lwnode/code/escargotshim/deps/minizip/unzip.h [new file with mode: 0644]
lwnode/code/escargotshim/escargotshim.gyp
lwnode/code/escargotshim/include/lwnode/lwnode.h
lwnode/code/escargotshim/src/api-data.cc
lwnode/code/escargotshim/src/api-scripts.cc
lwnode/code/escargotshim/src/api.h
lwnode/code/escargotshim/src/api/context.cc
lwnode/code/escargotshim/src/api/context.h
lwnode/code/escargotshim/src/api/engine.cc
lwnode/code/escargotshim/src/api/es-helper.cc
lwnode/code/escargotshim/src/api/isolate.cc
lwnode/code/escargotshim/src/api/stack-trace.cc
lwnode/code/escargotshim/src/api/utils.h
lwnode/code/escargotshim/src/api/utils/string-util.h [moved from lwnode/code/escargotshim/src/api/utils/string.h with 100% similarity]
lwnode/code/escargotshim/src/lwnode.cc
node.gyp
packaging/lwnode.spec
src/node_native_module.cc
src/node_native_module.h
src/node_native_module_lwnode-inl.h [new file with mode: 0644]
src/node_platform.cc
src/node_platform.h
tools/js2c.py

index 5a93981..5f64ff6 100755 (executable)
         'cflags': [ '-Wfatal-errors', '-Os' ],
       },
     },
+    'all_dependent_settings': {
+      'configurations': {
+        'Release': {
+          'defines': ['NDEBUG'],
+        },
+      },
+    },
     'conditions': [
       ['target_os=="tizen"', {
         'target_defaults': {
index 763e1c0..0ccf7d9 100644 (file)
@@ -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)
index d9e3db6..77974ef 100755 (executable)
 #include <thread>
 #include <mutex>
 #include <atomic>
+#include <condition_variable>
 #endif
 
 extern "C" {
index 0e9a964..7e3c1c2 100644 (file)
@@ -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<Evaluator::StackTraceData> 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;
index 216bbb1..2014b38 100644 (file)
@@ -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
index 83aec02..4965259 100644 (file)
@@ -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<Object*> 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<Object*> 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<Object*> 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<Object*> 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<Object*> 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<Object*> 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<int64_t>(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<Object*> 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<int64_t>(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
index 8216f25..409c084 100644 (file)
@@ -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
index 5a81337..04f76cf 100644 (file)
@@ -102,7 +102,7 @@ static Value asyncFromSyncIteratorContinuation(ExecutionState& state, Object* re
 
 static Value builtinAsyncFromSyncIteratorNext(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional<Object*> 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<Object*> 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);
index 4835ade..041852c 100644 (file)
@@ -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__);
index 612e71f..1921b5a 100644 (file)
@@ -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 (file)
index d58c145..0000000
+++ /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<Object*> 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
index 7ea0d7c..4018e7e 100644 (file)
@@ -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<int8_t>(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<Object*> 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<double>::infinity()) {
+        t = std::numeric_limits<double>::infinity();
+    } else if (q == -std::numeric_limits<double>::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<int32_t*>(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<int32_t>(rawStart, rawBytes);
+        break;
+    case TypedArrayType::BigInt64:
+        atomicLoad<int64_t>(rawStart, rawBytes);
+        break;
+    default:
+        RELEASE_ASSERT_NOT_REACHED();
+        break;
+    }
+    w = TypedArrayHelper::rawBytesToNumber(state, arrayTypeName, rawBytes);
+#else
+    {
+        std::lock_guard<SpinLock> 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<std::mutex> ul(WL->m_conditionVariableMutex);
+    WL->m_waiterCount++;
+    WL->m_mutex.unlock();
+    if (t == std::numeric_limits<double>::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<Object*> 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<double>::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<int32_t*>(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<Object*> 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
index c0a27e4..73ac0e6 100644 (file)
@@ -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
index 1a07a2f..56560a3 100644 (file)
@@ -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
index 5ca74af..5d9e1e5 100644 (file)
@@ -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
index 6ccfc5f..dc89198 100644 (file)
@@ -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
index e0bd9c6..3558c7c 100644 (file)
 
 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<Object*> 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<Object*> 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<Object*> 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
index e2ca14c..312691f 100644 (file)
@@ -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
index 197cb7f..d5761b6 100644 (file)
@@ -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<Object*> 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)));
 }
index 3014125..8f2dc53 100644 (file)
@@ -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);
index cfa9c67..e114ca7 100644 (file)
@@ -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<Object*> 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<Object*> 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<Object*> 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<Object*> 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<Object*> 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 (file)
index 33edc15..0000000
+++ /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<Object*> 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
index 7f179ae..9036522 100644 (file)
@@ -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),
index d509e13..078fe2d 100644 (file)
@@ -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
index e54ae9f..543e2e3 100644 (file)
@@ -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
index e74e11a..e309398 100644 (file)
@@ -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<double>::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
index f86b8a2..c2ce374 100644 (file)
@@ -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<Object*> 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<Object*> 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<Object*> 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<Object*> 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<Object*> 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<Object*> 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)));
 
index 4949c79..c9b68a3 100644 (file)
@@ -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
index c3f8ace..b2b2aef 100644 (file)
@@ -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
index ee8f6ef..4efa5cf 100644 (file)
@@ -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
index ee14b7b..a502f88 100644 (file)
@@ -753,8 +753,22 @@ std::pair<Value, bool> 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
index 31c6823..0c37e18 100644 (file)
@@ -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
index fc4ddb0..335ddd1 100644 (file)
@@ -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<Object*> 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
index 0f5ebb4..7770a9e 100644 (file)
@@ -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
index 5e848f6..d859031 100644 (file)
@@ -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
index 4b607e2..16861cb 100644 (file)
@@ -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<Object*> 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<Object*> 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<Object*> 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<int64_t>(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<Object*> 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<int64_t>(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<Object*> 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),
index e272011..39c8825 100644 (file)
@@ -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
index b5c122e..b0dbcaf 100644 (file)
@@ -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
index a73d967..5a72891 100644 (file)
@@ -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
index 57c3ab8..18a1947 100644 (file)
 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<name*>(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<ExecutionPause*>(curCode)->m_reason == ExecutionPause::Yield) {
+                curPos += static_cast<ExecutionPause*>(curCode)->m_yieldData.m_tailDataLength;
+            } else if (static_cast<ExecutionPause*>(curCode)->m_reason == ExecutionPause::Await) {
+                curPos += static_cast<ExecutionPause*>(curCode)->m_awaitData.m_tailDataLength;
+            } else if (static_cast<ExecutionPause*>(curCode)->m_reason == ExecutionPause::GeneratorsInitialize) {
+                curPos += static_cast<ExecutionPause*>(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
 
index 643158a..1f6cdda 100644 (file)
@@ -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
 };
index 7d90161..27ee6be 100644 (file)
@@ -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");
     }
 }
index 22952e7..38feaa9 100644 (file)
@@ -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)
index c7e236a..fda957f 100644 (file)
@@ -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<std::string> subtags;
@@ -1808,6 +1896,33 @@ Value Intl::getOption(ExecutionState& state, Object* options, Value property, In
     }
 }
 
+template <typename T>
+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<std::string> initAvailableNumberingSystems()
 {
     std::vector<std::string> availableNumberingSystems;
index 595bdce..020d2e1 100644 (file)
@@ -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 <typename T>
+    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<std::string> calendarsForLocale(String* locale);
index 3c0926a..0551119 100644 (file)
@@ -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<std::string> 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<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:
+    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<UDateTimePatternGenerator> 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<void(String * prop, Value * values, size_t valuesSize)> 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<void(String * prop, Value * values, size_t valuesSize)> doTable4 = [&](String* prop, Value* values, size_t valuesSize) {
         Value value = Intl::getOption(state, options.asObject(), prop, Intl::StringValue, values, valuesSize, Value());
         // Set opt.[[<prop>]] 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.[[<prop>]] 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.[[<dataLocale>]].
+
+    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<UDateTimePatternGenerator> 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.[[<prop>]].
+        // 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]].[[<calendar>]].
+        // 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<UDateFormat> 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]].[[<calendar>]].
+        // 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 [[<prop>]], then
+    // Let p be bestFormat.[[<prop>]].
+    // 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<UCalendar*>(udat_getCalendar(icuDateFormat));
+    UCalendar* cal = const_cast<UCalendar*>(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
index 49eda7a..940a2f4 100644 (file)
 
 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
index 21454f7..d05d7ca 100644 (file)
@@ -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()));
index 9ab701f..ca5d782 100644 (file)
@@ -173,16 +173,25 @@ struct InterpretedCodeBlockRareData : public gc {
     FunctionContextVarMap* m_identifierInfoMap;
     TightVector<Optional<ArrayObject*>, GCUtil::gc_malloc_allocator<Optional<ArrayObject*>>> 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)
index 24fa9de..3cffead 100644 (file)
@@ -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 */
     {
     }
 };
index 219bde4..694c6a9 100644 (file)
@@ -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, « »).
index 7a9d49e..a42b5ed 100644 (file)
@@ -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);
         }
index 2119cb6..7beae99 100644 (file)
@@ -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 {
index d63fa92..bc035de 100644 (file)
@@ -1612,7 +1612,7 @@ public:
     }
 
     template <class ASTBuilder>
-    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 <class ASTBuilder>
-    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 <class ASTBuilder>
-    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<ASTBuilder, false>);
             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();
index 35fb1c0..e72107f 100644 (file)
@@ -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));
         }
     }
 
index efc877a..8a4eb30 100644 (file)
@@ -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)
index 1be3fcc..da5d6f9 100644 (file)
@@ -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
index 6d69bb2..24c2083 100644 (file)
@@ -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)));
     }
 }
 
index 489961a..46f8e99 100644 (file)
@@ -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::Waiter*> 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<Waiter*>().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<std::mutex> 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
index 38cdd49..3e58407 100644 (file)
 #ifndef __EscargotGlobal__
 #define __EscargotGlobal__
 
+#if defined(ENABLE_THREADING)
+#include <mutex>
+#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<Waiter*> g_waiter;
+    static Waiter* waiter(void* blockAddress);
+#endif
 };
 
 } // namespace Escargot
index fb9909b..c01cfc4 100644 (file)
@@ -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<Object*> 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<Object*> 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<Object*> 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<Object*> 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<Object*> 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<Object*> newTarget)
+static Value builtinArrayToString(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional<Object*> 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<Object*> 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 }.
index 8368f98..831ce11 100644 (file)
@@ -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<Object*> 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 <typename TA, int elementSize>
     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
 
index b6e715d..f0e1dfa 100644 (file)
@@ -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;
index 4f81a1a..56ce9fc 100644 (file)
@@ -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<uint8_t>(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<uint8_t>(ElementTypes::Undefined));
+        } else if (next.isNull()) {
+            validType = allTypes || (elementTypes & static_cast<uint8_t>(ElementTypes::Null));
+        } else if (next.isBoolean()) {
+            validType = allTypes || (elementTypes & static_cast<uint8_t>(ElementTypes::Boolean));
+        } else if (next.isString()) {
+            validType = allTypes || (elementTypes & static_cast<uint8_t>(ElementTypes::String));
+        } else if (next.isSymbol()) {
+            validType = allTypes || (elementTypes & static_cast<uint8_t>(ElementTypes::Symbol));
+        } else if (next.isNumber()) {
+            validType = allTypes || (elementTypes & static_cast<uint8_t>(ElementTypes::Number));
+        } else if (next.isBigInt()) {
+            validType = allTypes || (elementTypes & static_cast<uint8_t>(ElementTypes::BigInt));
+        } else if (next.isObject()) {
+            validType = allTypes || (elementTypes & static_cast<uint8_t>(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"))
index f1bcf7c..7cdd8b0 100644 (file)
@@ -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<uint8_t>(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
 
index 5c2888e..98fc653 100644 (file)
@@ -48,6 +48,8 @@ public:
     virtual void didLoadModule(Context* relatedContext, Optional<Script*> 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;
index dc0c61f..7ca0c53 100644 (file)
@@ -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());
index 9b7d518..f8ee769 100644 (file)
@@ -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<uint8_t>(ElementTypes::String) | static_cast<uint8_t>(ElementTypes::Symbol)));
 
     // If trapResult contains any duplicate entries, throw a TypeError exception
     for (size_t i = 0; i < trapResult.size(); i++) {
index 26acbdb..93bfe03 100644 (file)
@@ -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<LexicalEnvironment*>(nullptr), argc, argv, m_codeBlock->asInterpretedCodeBlock()->isStrict());
+    ErrorObject::throwBuiltinError(newState, ErrorObject::TypeError, "Arrow function cannot be invoked with 'new'");
     ASSERT_NOT_REACHED();
     return Value();
 }
index 74fd3f7..e0bceb8 100644 (file)
@@ -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<LexicalEnvironment*>(nullptr), argc, argv, m_codeBlock->asInterpretedCodeBlock()->isStrict());
+    ErrorObject::throwBuiltinError(newState, ErrorObject::TypeError, "Async function cannot be invoked with 'new'");
     ASSERT_NOT_REACHED();
     return Value();
 }
index e96f41a..596a288 100644 (file)
@@ -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<LexicalEnvironment*>(nullptr), argc, argv, m_codeBlock->asInterpretedCodeBlock()->isStrict());
+    ErrorObject::throwBuiltinError(newState, ErrorObject::TypeError, "AsyncGenerator cannot be invoked with 'new'");
     ASSERT_NOT_REACHED();
     return Value();
 }
index 66eda44..455ca1c 100644 (file)
@@ -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<LexicalEnvironment*>(nullptr), argc, argv, m_codeBlock->asInterpretedCodeBlock()->isStrict());
+    ErrorObject::throwBuiltinError(newState, ErrorObject::TypeError, "Class constructor cannot be invoked without 'new'");
     return Value();
 }
 
index 0f9300e..2ac6c13 100644 (file)
@@ -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<LexicalEnvironment*>(nullptr), argc, argv, m_codeBlock->asInterpretedCodeBlock()->isStrict());
+    ErrorObject::throwBuiltinError(newState, ErrorObject::TypeError, "Generator cannot be invoked with 'new'");
     ASSERT_NOT_REACHED();
     return Value();
 }
index e08a120..7332f69 100644 (file)
@@ -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<LexicalEnvironment*>(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<LexicalEnvironment*>(nullptr), argc, argv, m_codeBlock->asInterpretedCodeBlock()->isStrict());
+    ErrorObject::throwBuiltinError(newState, ErrorObject::TypeError, "This function cannot be invoked");
     ASSERT_NOT_REACHED();
     return Value();
 }
index e2f86a5..e1c4e92 100644 (file)
@@ -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
index b77e02e..b677135 100644 (file)
@@ -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
index f30fef0..2e9cf06 100644 (file)
@@ -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<std::tuple<std::string /* abs path */, ContextRef*, PersistentRefHolder<ScriptRef>>>();
@@ -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;
@@ -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<Object*> 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<Object*> 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
 
index 712ddf7..8af46bb 100644 (file)
@@ -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
 #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
index 4c96294..c7ecbbc 100644 (file)
@@ -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 (file)
index 0000000..c2b95a5
--- /dev/null
@@ -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 (file)
index 0000000..fedc20d
--- /dev/null
@@ -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 (file)
index 0000000..ffb6682
--- /dev/null
@@ -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 (file)
index 0000000..dafa14c
--- /dev/null
@@ -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 (file)
index 0000000..1e9e820
--- /dev/null
@@ -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<RAND_HEAD_LEN)
+      return 0;
+
+    /* First generate RAND_HEAD_LEN-2 random bytes. We encrypt the
+     * output of rand() to get less predictability, since rand() is
+     * often poorly implemented.
+     */
+    if (++calls == 1)
+    {
+        srand((unsigned)(time(NULL) ^ ZCR_SEED2));
+    }
+    init_keys(passwd, pkeys, pcrc_32_tab);
+    for (n = 0; n < RAND_HEAD_LEN-2; n++)
+    {
+        c = (rand() >> 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 (file)
index 0000000..543910b
--- /dev/null
@@ -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 (file)
index 0000000..8dcbdb0
--- /dev/null
@@ -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 <stdio.h>
+#include <stdlib.h>
+#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 <stdint.h>
+    #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 (executable)
index 0000000..7b1421e
--- /dev/null
@@ -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 (file)
index 0000000..c5737eb
--- /dev/null
@@ -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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "zlib.h"
+#include "unzip.h"
+
+#ifdef STDC
+#  include <stddef.h>
+#  include <string.h>
+#  include <stdlib.h>
+#endif
+#ifdef NO_ERRNO_H
+    extern int errno;
+#else
+#   include <errno.h>
+#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 (c1<c2)
+            return -1;
+        if (c1>c2)
+            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 (uBackRead<uMaxBack)
+    {
+        uLong uReadSize;
+        ZPOS64_T uReadPos ;
+        int i;
+        if (uBackRead+BUFREADCOMMENT>uMaxBack)
+            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 (uBackRead<uMaxBack)
+    {
+        uLong uReadSize;
+        ZPOS64_T uReadPos;
+        int i;
+        if (uBackRead+BUFREADCOMMENT>uMaxBack)
+            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_pos<us.offset_central_dir+us.size_central_dir) &&
+        (err==UNZ_OK))
+        err=UNZ_BADZIPFILE;
+
+    if (err!=UNZ_OK)
+    {
+        ZCLOSE64(us.z_filefunc, us.filestream);
+        return NULL;
+    }
+
+    us.byte_before_the_zipfile = central_pos -
+                            (us.offset_central_dir+us.size_central_dir);
+    us.central_pos = central_pos;
+    us.pfile_in_zip_read = NULL;
+    us.encrypted = 0;
+
+
+    s=(unz64_s*)ALLOC(sizeof(unz64_s));
+    if( s != NULL)
+    {
+        *s=us;
+        unzGoToFirstFile((unzFile)s);
+    }
+    return (unzFile)s;
+}
+
+
+extern unzFile ZEXPORT unzOpen2 (const char *path,
+                                        zlib_filefunc_def* pzlib_filefunc32_def)
+{
+    if (pzlib_filefunc32_def != NULL)
+    {
+        zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
+        fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill,pzlib_filefunc32_def);
+        return unzOpenInternal(path, &zlib_filefunc64_32_def_fill, 0);
+    }
+    else
+        return unzOpenInternal(path, NULL, 0);
+}
+
+extern unzFile ZEXPORT unzOpen2_64 (const void *path,
+                                     zlib_filefunc64_def* pzlib_filefunc_def)
+{
+    if (pzlib_filefunc_def != NULL)
+    {
+        zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
+        zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def;
+        zlib_filefunc64_32_def_fill.ztell32_file = NULL;
+        zlib_filefunc64_32_def_fill.zseek32_file = NULL;
+        return unzOpenInternal(path, &zlib_filefunc64_32_def_fill, 1);
+    }
+    else
+        return unzOpenInternal(path, NULL, 1);
+}
+
+extern unzFile ZEXPORT unzOpen (const char *path)
+{
+    return unzOpenInternal(path, NULL, 0);
+}
+
+extern unzFile ZEXPORT unzOpen64 (const void *path)
+{
+    return unzOpenInternal(path, NULL, 1);
+}
+
+/*
+  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 unzClose (unzFile file)
+{
+    unz64_s* s;
+    if (file==NULL)
+        return UNZ_PARAMERROR;
+    s=(unz64_s*)file;
+
+    if (s->pfile_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_filename<fileNameBufferSize)
+        {
+            *(szFileName+file_info.size_filename)='\0';
+            uSizeRead = file_info.size_filename;
+        }
+        else
+            uSizeRead = fileNameBufferSize;
+
+        if ((file_info.size_filename>0) && (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_extra<extraFieldBufferSize)
+            uSizeRead = file_info.size_file_extra;
+        else
+            uSizeRead = extraFieldBufferSize;
+
+        if (lSeek!=0)
+        {
+            if (ZSEEK64(s->z_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_comment<commentBufferSize)
+        {
+            *(szComment+file_info.size_file_comment)='\0';
+            uSizeRead = file_info.size_file_comment;
+        }
+        else
+            uSizeRead = commentBufferSize;
+
+        if (lSeek!=0)
+        {
+            if (ZSEEK64(s->z_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_compressed<uReadThis)
+                uReadThis = (uInt)pfile_in_zip_read_info->rest_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;i<uReadThis;i++)
+                  pfile_in_zip_read_info->read_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;i<uDoCopy;i++)
+                *(pfile_in_zip_read_info->stream.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 (file)
index 0000000..2104e39
--- /dev/null
@@ -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 */
index 6d7c967..5392388 100755 (executable)
         ],
         '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"', {
index d196252..98a4b60 100644 (file)
@@ -26,6 +26,12 @@ void InitializeProcessMethods(v8::Local<v8::Object> 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<v8::String> NewReloadableStringFromOneByte(
+  static v8::MaybeLocal<v8::String> NewReloadableString(
       v8::Isolate* isolate,
       ReloadableSourceData* data,
       LoadCallback loadCallback,
index e3f9d89..fae9c88 100644 (file)
@@ -1609,15 +1609,7 @@ Local<v8::Context> v8::Object::CreationContext() {
     return Local<v8::Context>();
   }
 
-  auto globalObjectData =
-      ObjectRefHelper::getExtraData(esVal.get()->globalObject())
-          ->asGlobalObjectData();
-
-  LWNODE_CHECK(globalObjectData->internalFieldCount() ==
-               GlobalObjectData::kInternalFieldCount);
-
-  auto lwCreationContext = reinterpret_cast<ContextWrap*>(
-      globalObjectData->internalField(GlobalObjectData::kContextWrapSlot));
+  auto lwCreationContext = ContextWrap::fromEscargot(esVal.get());
 
   return v8::Local<v8::Context>::New(
       lwIsolate->toV8(),
index 97c07ef..a53bb7e 100644 (file)
@@ -269,6 +269,12 @@ MaybeLocal<UnboundScript> 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<UnboundScript>();
   }
 
index 6bca167..f26624f 100644 (file)
@@ -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;
 
index da85006..fc576a5 100644 (file)
@@ -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<ContextWrap*>(
+      globalObjectData->internalField(GlobalObjectData::kContextWrapSlot));
+  return lwCreationContext;
+}
+
 void ContextWrap::Enter() {
   isolate_->Enter();
   isolate_->pushContext(this);
index 81ce211..4edfa7c 100644 (file)
@@ -29,6 +29,7 @@ typedef GCUnorderedMap<int, void*> EmbedderDataMap;
 class ContextWrap : public ValueWrap {
  public:
   static ContextWrap* New(IsolateWrap* isolate);
+  static ContextWrap* fromEscargot(Escargot::ContextRef* context);
 
   void Enter();
   void Exit();
index 7861697..d3a6d05 100644 (file)
@@ -19,7 +19,7 @@
 #include <sstream>
 #include "handle.h"
 #include "utils/misc.h"
-#include "utils/string.h"
+#include "utils/string-util.h"
 
 using namespace Escargot;
 
index bf98eb1..259edb1 100755 (executable)
@@ -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 <sstream>
 
index f7f30d1..a665c2f 100755 (executable)
@@ -216,8 +216,8 @@ IsolateWrap::IsolateWrap() {
   globalHandles_ = new GlobalHandles(toV8());
 
   privateValuesSymbol_ = PersistentRefHolder<SymbolRef>(
-      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();
index d48642f..c62de4b 100644 (file)
@@ -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());
       });
 }
 
index fd24174..25d53b2 100644 (file)
@@ -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"
index 3c69a6d..647b0c6 100644 (file)
 
 #include "lwnode/lwnode.h"
 #include <EscargotPublic.h>
+#include <malloc.h>  // for malloc_trim
 #include <chrono>
 #include <fstream>
 #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<Object> target, Local<Context> 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<String> Utils::NewReloadableStringFromOneByte(
-    Isolate* isolate,
-    ReloadableSourceData* data,
-    LoadCallback loadCallback,
-    UnloadCallback unloadCallback) {
+MaybeLocal<String> Utils::NewReloadableString(Isolate* isolate,
+                                              ReloadableSourceData* data,
+                                              LoadCallback loadCallback,
+                                              UnloadCallback unloadCallback) {
   MaybeLocal<String> result;
 
   if (data->preloadedDataLength() == 0) {
@@ -181,7 +187,7 @@ MaybeLocal<String> 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<String> 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
index 0de1fb4..49693ce 100644 (file)
--- a/node.gyp
+++ b/node.gyp
           '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': [
           '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)',
+              ],
+            }]
           ],
         },
       ],
index 9f29476..c90cd5a 100644 (file)
@@ -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
index 4c3633e..d687af4 100644 (file)
@@ -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<String> 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);
 
index 3be3f23..1639a70 100644 (file)
@@ -39,6 +39,12 @@ class NativeModuleLoader {
   friend class NativeModuleEnv;
   friend class CodeCacheBuilder;
 
+  // @lwnode
+  inline bool IsOneByte(const char* id);
+  v8::MaybeLocal<v8::String> 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 (file)
index 0000000..e8268d1
--- /dev/null
@@ -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 <unzip.h>
+#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<String> 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<String>();
+  }
+
+  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<Utils::ReloadableSourceData*>(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<Utils::ReloadableSourceData*>(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
index 9f97bf1..a842e84 100644 (file)
@@ -219,6 +219,13 @@ int WorkerThreadsTaskRunner::NumberOfWorkerThreads() const {
   return threads_.size();
 }
 
+#ifdef LWNODE
+void PerIsolatePlatformData::PrepareTask(uv_prepare_t *handle) {
+  auto data = reinterpret_cast<PerIsolatePlatformData*>(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<void*>(this);
   uv_unref(reinterpret_cast<uv_handle_t*>(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<void*>(this);
+  uv_unref(reinterpret_cast<uv_handle_t*>(prepare_task_));
+#endif
 }
 
 std::shared_ptr<v8::TaskRunner>
@@ -329,6 +344,13 @@ void PerIsolatePlatformData::AddShutdownCallback(void (*callback)(void*),
 }
 
 void PerIsolatePlatformData::Shutdown() {
+#ifdef LWNODE
+  if (prepare_task_) {
+    uv_close(reinterpret_cast<uv_handle_t*>(prepare_task_), nullptr);
+    prepare_task_ = nullptr;
+  }
+#endif
+
   if (flush_tasks_ == nullptr)
     return;
 
index dc512dd..f3d24f8 100644 (file)
@@ -106,6 +106,11 @@ class PerIsolatePlatformData :
   TaskQueue<v8::Task> foreground_tasks_;
   TaskQueue<DelayedTask> 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<DelayedTask, void(*)(DelayedTask*)>
       DelayedTaskPointer;
index 195e6a6..d2f5f1c 100755 (executable)
@@ -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__":