#include "config.h"
#include "APICast.h"
#include "JSCInlines.h"
#include "JSCast.h"
#include "ThrowScope.h"
#include "JSGlobalObject.h"
#include "ProxyObject.h"
#include "JSPromise.h"
#include "JSMap.h"
#include "JSSet.h"
#include "JSMapIterator.h"
#include "JSSetIterator.h"
#include "JSWeakMap.h"
#include "JSWeakSet.h"
#include "WeakMapImpl.h"
#include "WeakMapImplInlines.h"
#include "ArgList.h"
#include "IterationKind.h"
#include "ArrayConstructor.h"
#include "ObjectConstructor.h"
#include <JavaScriptCore/JavaScript.h>
using namespace JSC;
extern "C" {
JSValueRef v82jsc_proxy_handler(JSContextRef ctxRef, JSValueRef value)
{
JSGlobalObject* globalObject = toJS(ctxRef);
VM& vm = globalObject->vm();
JSLockHolder lock(vm);
JSValue v = toJS(globalObject, value);
if (auto* proxy = dynamicDowncast<ProxyObject>(v))
return toRef(globalObject, proxy->handler());
return nullptr;
}
int v82jsc_promise_status(JSContextRef ctxRef, JSValueRef value,
JSValueRef* resultOut)
{
JSGlobalObject* globalObject = toJS(ctxRef);
VM& vm = globalObject->vm();
JSLockHolder lock(vm);
JSValue v = toJS(globalObject, value);
auto* promise = dynamicDowncast<JSPromise>(v);
if (!promise)
return -1;
JSPromise::Status status = promise->status();
if (resultOut) {
if (status == JSPromise::Status::Pending)
*resultOut = nullptr;
else
*resultOut = toRef(globalObject, promise->result());
}
return static_cast<int>(status);
}
JSValueRef v82jsc_iterator_preview(JSContextRef ctxRef, JSValueRef value,
bool* isKeyValueOut)
{
JSGlobalObject* globalObject = toJS(ctxRef);
VM& vm = globalObject->vm();
JSLockHolder lock(vm);
auto scope = DECLARE_THROW_SCOPE(vm);
JSValue v = toJS(globalObject, value);
JSArray* out = constructEmptyArray(globalObject, nullptr);
if (!out)
return nullptr;
unsigned idx = 0;
if (auto* it = dynamicDowncast<JSMapIterator>(v)) {
bool kv = it->kind() == IterationKind::Entries;
if (isKeyValueOut)
*isKeyValueOut = kv;
JSMapIterator* fresh = JSMapIterator::create(
vm, globalObject->mapIteratorStructure(), it->iteratedObject(),
it->kind());
JSValue entry;
while (fresh->next(globalObject, entry)) {
if (scope.exception()) { (void)scope.tryClearException(); break; }
if (kv && entry.isObject()) {
JSValue k = entry.get(globalObject, static_cast<unsigned>(0));
JSValue val = entry.get(globalObject, static_cast<unsigned>(1));
(void)scope.tryClearException();
out->putDirectIndex(globalObject, idx++, k);
out->putDirectIndex(globalObject, idx++, val);
} else {
out->putDirectIndex(globalObject, idx++, entry);
}
}
return toRef(globalObject, out);
}
if (auto* it = dynamicDowncast<JSSetIterator>(v)) {
bool kv = it->kind() == IterationKind::Entries;
if (isKeyValueOut)
*isKeyValueOut = kv;
JSSetIterator* fresh = JSSetIterator::create(
vm, globalObject->setIteratorStructure(), it->iteratedObject(),
it->kind());
JSValue entry;
while (fresh->next(globalObject, entry)) {
if (scope.exception()) { (void)scope.tryClearException(); break; }
if (kv && entry.isObject()) {
JSValue k = entry.get(globalObject, static_cast<unsigned>(0));
JSValue val = entry.get(globalObject, static_cast<unsigned>(1));
(void)scope.tryClearException();
out->putDirectIndex(globalObject, idx++, k);
out->putDirectIndex(globalObject, idx++, val);
} else {
out->putDirectIndex(globalObject, idx++, entry);
}
}
return toRef(globalObject, out);
}
if (auto* wm = dynamicDowncast<JSWeakMap>(v)) {
if (isKeyValueOut)
*isKeyValueOut = true;
MarkedArgumentBuffer buffer;
wm->takeSnapshot(buffer, 0);
for (unsigned i = 0; i < buffer.size(); ++i)
out->putDirectIndex(globalObject, idx++, buffer.at(i));
(void)scope.tryClearException();
return toRef(globalObject, out);
}
if (auto* ws = dynamicDowncast<JSWeakSet>(v)) {
if (isKeyValueOut)
*isKeyValueOut = false;
MarkedArgumentBuffer buffer;
ws->takeSnapshot(buffer, 0);
for (unsigned i = 0; i < buffer.size(); ++i)
out->putDirectIndex(globalObject, idx++, buffer.at(i));
(void)scope.tryClearException();
return toRef(globalObject, out);
}
return nullptr;
}
}