summaryrefslogtreecommitdiffstats
path: root/JavaScriptCore/qt
diff options
context:
space:
mode:
authorKristian Monsen <kristianm@google.com>2010-06-28 16:42:48 +0100
committerKristian Monsen <kristianm@google.com>2010-07-02 10:29:56 +0100
commit06ea8e899e48f1f2f396b70e63fae369f2f23232 (patch)
tree20c1428cd05c76f32394ab354ea35ed99acd86d8 /JavaScriptCore/qt
parent72aad67af14193199e29cdd5c4ddc095a8b9a8a8 (diff)
downloadexternal_webkit-06ea8e899e48f1f2f396b70e63fae369f2f23232.zip
external_webkit-06ea8e899e48f1f2f396b70e63fae369f2f23232.tar.gz
external_webkit-06ea8e899e48f1f2f396b70e63fae369f2f23232.tar.bz2
Merge WebKit at r61871: Initial merge by git.
Change-Id: I6cff43abca9cc4782e088a469ad4f03f166a65d5
Diffstat (limited to 'JavaScriptCore/qt')
-rw-r--r--JavaScriptCore/qt/api/qscriptengine_p.cpp2
-rw-r--r--JavaScriptCore/qt/api/qscriptvalue.cpp28
-rw-r--r--JavaScriptCore/qt/api/qscriptvalue.h4
-rw-r--r--JavaScriptCore/qt/api/qscriptvalue_p.h193
-rw-r--r--JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.cpp40
-rw-r--r--JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.h1
6 files changed, 186 insertions, 82 deletions
diff --git a/JavaScriptCore/qt/api/qscriptengine_p.cpp b/JavaScriptCore/qt/api/qscriptengine_p.cpp
index a6cf4a4..fd7978b 100644
--- a/JavaScriptCore/qt/api/qscriptengine_p.cpp
+++ b/JavaScriptCore/qt/api/qscriptengine_p.cpp
@@ -85,5 +85,5 @@ QScriptValuePrivate* QScriptEnginePrivate::newObject() const
QScriptValuePrivate* QScriptEnginePrivate::globalObject() const
{
JSObjectRef globalObject = JSContextGetGlobalObject(m_context);
- return new QScriptValuePrivate(this, globalObject, globalObject);
+ return new QScriptValuePrivate(this, globalObject);
}
diff --git a/JavaScriptCore/qt/api/qscriptvalue.cpp b/JavaScriptCore/qt/api/qscriptvalue.cpp
index 22ff8be..8ad76a5 100644
--- a/JavaScriptCore/qt/api/qscriptvalue.cpp
+++ b/JavaScriptCore/qt/api/qscriptvalue.cpp
@@ -518,6 +518,34 @@ QScriptEngine* QScriptValue::engine() const
}
/*!
+ If this QScriptValue is an object, returns the internal prototype
+ (\c{__proto__} property) of this object; otherwise returns an
+ invalid QScriptValue.
+
+ \sa setPrototype(), isObject()
+*/
+QScriptValue QScriptValue::prototype() const
+{
+ return QScriptValuePrivate::get(d_ptr->prototype());
+}
+
+/*!
+ If this QScriptValue is an object, sets the internal prototype
+ (\c{__proto__} property) of this object to be \a prototype;
+ otherwise does nothing.
+
+ The internal prototype should not be confused with the public
+ property with name "prototype"; the public prototype is usually
+ only set on functions that act as constructors.
+
+ \sa prototype(), isObject()
+*/
+void QScriptValue::setPrototype(const QScriptValue& prototype)
+{
+ d_ptr->setPrototype(QScriptValuePrivate::get(prototype));
+}
+
+/*!
Assigns the \a other value to this QScriptValue.
Note that if \a other is an object (isObject() returns true),
diff --git a/JavaScriptCore/qt/api/qscriptvalue.h b/JavaScriptCore/qt/api/qscriptvalue.h
index 6c42429..c82ef55 100644
--- a/JavaScriptCore/qt/api/qscriptvalue.h
+++ b/JavaScriptCore/qt/api/qscriptvalue.h
@@ -59,6 +59,10 @@ public:
~QScriptValue();
QScriptValue& operator=(const QScriptValue& other);
+
+ QScriptValue prototype() const;
+ void setPrototype(const QScriptValue& prototype);
+
bool equals(const QScriptValue& other) const;
bool strictlyEquals(const QScriptValue& other) const;
bool instanceOf(const QScriptValue& other) const;
diff --git a/JavaScriptCore/qt/api/qscriptvalue_p.h b/JavaScriptCore/qt/api/qscriptvalue_p.h
index 1bb8a77..f8a1e7a 100644
--- a/JavaScriptCore/qt/api/qscriptvalue_p.h
+++ b/JavaScriptCore/qt/api/qscriptvalue_p.h
@@ -25,6 +25,7 @@
#include "qscriptvalue.h"
#include <JavaScriptCore/JavaScript.h>
#include <JavaScriptCore/JSRetainPtr.h>
+#include <JSObjectRefPrivate.h>
#include <QtCore/qmath.h>
#include <QtCore/qnumeric.h>
#include <QtCore/qshareddata.h>
@@ -49,7 +50,7 @@ class QScriptValue;
CNumber -> QSVP is created from int, uint, double... and no JSC engine has been bind yet. Current
value is kept in m_number
CBool -> QSVP is created from bool and no JSC engine has been associated yet. Current value is kept
- in m_number
+ in m_bool
CNull -> QSVP is null, but a JSC engine hasn't been associated yet.
CUndefined -> QSVP is undefined, but a JSC engine hasn't been associated yet.
JSValue -> QSVP is associated with engine, but there is no information about real type, the state
@@ -89,7 +90,7 @@ public:
inline QScriptValuePrivate(const QScriptEnginePrivate* engine, QScriptValue::SpecialValue value);
inline QScriptValuePrivate(const QScriptEnginePrivate* engine, JSValueRef value);
- inline QScriptValuePrivate(const QScriptEnginePrivate* engine, JSValueRef value, JSObjectRef object);
+ inline QScriptValuePrivate(const QScriptEnginePrivate* engine, JSObjectRef object);
inline bool isValid() const;
inline bool isBool();
@@ -108,8 +109,11 @@ public:
inline qint32 toInt32() const;
inline quint32 toUInt32() const;
inline quint16 toUInt16() const;
+
inline QScriptValuePrivate* toObject(QScriptEnginePrivate* engine);
inline QScriptValuePrivate* toObject();
+ inline QScriptValuePrivate* prototype();
+ inline void setPrototype(QScriptValuePrivate* prototype);
inline bool equals(QScriptValuePrivate* other);
inline bool strictlyEquals(QScriptValuePrivate* other);
@@ -137,12 +141,23 @@ private:
JSObject
} m_state;
QScriptEnginePtr m_engine;
- QString m_string;
- qsreal m_number;
- JSValueRef m_value;
- JSObjectRef m_object;
-
- inline void setValue(JSValueRef);
+ union Value
+ {
+ bool m_bool;
+ qsreal m_number;
+ JSValueRef m_value;
+ JSObjectRef m_object;
+ QString* m_string;
+
+ Value() : m_number(0) {}
+ Value(bool value) : m_bool(value) {}
+ Value(int number) : m_number(number) {}
+ Value(uint number) : m_number(number) {}
+ Value(qsreal number) : m_number(number) {}
+ Value(JSValueRef value) : m_value(value) {}
+ Value(JSObjectRef object) : m_object(object) {}
+ Value(QString* string) : m_string(string) {}
+ } u;
inline bool inherits(const char*);
inline State refinedJSValue();
@@ -166,131 +181,124 @@ QScriptValue QScriptValuePrivate::get(QScriptValuePrivate* d)
QScriptValuePrivate::~QScriptValuePrivate()
{
- if (m_value)
- JSValueUnprotect(*m_engine, m_value);
+ if (isJSBased())
+ JSValueUnprotect(*m_engine, u.m_value);
+ else if (isStringBased())
+ delete u.m_string;
}
QScriptValuePrivate::QScriptValuePrivate()
: m_state(Invalid)
- , m_value(0)
{
}
QScriptValuePrivate::QScriptValuePrivate(const QString& string)
: m_state(CString)
- , m_string(string)
- , m_value(0)
+ , u(new QString(string))
{
}
QScriptValuePrivate::QScriptValuePrivate(bool value)
: m_state(CBool)
- , m_number(value)
- , m_value(0)
+ , u(value)
{
}
QScriptValuePrivate::QScriptValuePrivate(int number)
: m_state(CNumber)
- , m_number(number)
- , m_value(0)
+ , u(number)
{
}
QScriptValuePrivate::QScriptValuePrivate(uint number)
: m_state(CNumber)
- , m_number(number)
- , m_value(0)
+ , u(number)
{
}
QScriptValuePrivate::QScriptValuePrivate(qsreal number)
: m_state(CNumber)
- , m_number(number)
- , m_value(0)
+ , u(number)
{
}
QScriptValuePrivate::QScriptValuePrivate(QScriptValue::SpecialValue value)
: m_state(value == QScriptValue::NullValue ? CNull : CUndefined)
- , m_value(0)
{
}
QScriptValuePrivate::QScriptValuePrivate(const QScriptEnginePrivate* engine, bool value)
: m_state(JSPrimitive)
, m_engine(const_cast<QScriptEnginePrivate*>(engine))
- , m_value(engine->makeJSValue(value))
+ , u(engine->makeJSValue(value))
{
Q_ASSERT(engine);
- JSValueProtect(*m_engine, m_value);
+ JSValueProtect(*m_engine, u.m_value);
}
QScriptValuePrivate::QScriptValuePrivate(const QScriptEnginePrivate* engine, int value)
: m_state(JSPrimitive)
, m_engine(const_cast<QScriptEnginePrivate*>(engine))
- , m_value(m_engine->makeJSValue(value))
+ , u(m_engine->makeJSValue(value))
{
Q_ASSERT(engine);
- JSValueProtect(*m_engine, m_value);
+ JSValueProtect(*m_engine, u.m_value);
}
QScriptValuePrivate::QScriptValuePrivate(const QScriptEnginePrivate* engine, uint value)
: m_state(JSPrimitive)
, m_engine(const_cast<QScriptEnginePrivate*>(engine))
- , m_value(m_engine->makeJSValue(value))
+ , u(m_engine->makeJSValue(value))
{
Q_ASSERT(engine);
- JSValueProtect(*m_engine, m_value);
+ JSValueProtect(*m_engine, u.m_value);
}
QScriptValuePrivate::QScriptValuePrivate(const QScriptEnginePrivate* engine, qsreal value)
: m_state(JSPrimitive)
, m_engine(const_cast<QScriptEnginePrivate*>(engine))
- , m_value(m_engine->makeJSValue(value))
+ , u(m_engine->makeJSValue(value))
{
Q_ASSERT(engine);
- JSValueProtect(*m_engine, m_value);
+ JSValueProtect(*m_engine, u.m_value);
}
QScriptValuePrivate::QScriptValuePrivate(const QScriptEnginePrivate* engine, const QString& value)
: m_state(JSPrimitive)
, m_engine(const_cast<QScriptEnginePrivate*>(engine))
- , m_value(m_engine->makeJSValue(value))
+ , u(m_engine->makeJSValue(value))
{
Q_ASSERT(engine);
- JSValueProtect(*m_engine, m_value);
+ JSValueProtect(*m_engine, u.m_value);
}
QScriptValuePrivate::QScriptValuePrivate(const QScriptEnginePrivate* engine, QScriptValue::SpecialValue value)
: m_state(JSPrimitive)
, m_engine(const_cast<QScriptEnginePrivate*>(engine))
- , m_value(m_engine->makeJSValue(value))
+ , u(m_engine->makeJSValue(value))
{
Q_ASSERT(engine);
- JSValueProtect(*m_engine, m_value);
+ JSValueProtect(*m_engine, u.m_value);
}
QScriptValuePrivate::QScriptValuePrivate(const QScriptEnginePrivate* engine, JSValueRef value)
: m_state(JSValue)
, m_engine(const_cast<QScriptEnginePrivate*>(engine))
- , m_value(value)
+ , u(value)
{
Q_ASSERT(engine);
Q_ASSERT(value);
- JSValueProtect(*m_engine, m_value);
+ JSValueProtect(*m_engine, u.m_value);
}
-QScriptValuePrivate::QScriptValuePrivate(const QScriptEnginePrivate* engine, JSValueRef value, JSObjectRef object)
+QScriptValuePrivate::QScriptValuePrivate(const QScriptEnginePrivate* engine, JSObjectRef object)
: m_state(JSObject)
, m_engine(const_cast<QScriptEnginePrivate*>(engine))
- , m_value(value)
- , m_object(object)
+ , u(object)
{
Q_ASSERT(engine);
- Q_ASSERT(value);
Q_ASSERT(object);
- JSValueProtect(*m_engine, m_value);
+ JSValueProtect(*m_engine, object);
}
bool QScriptValuePrivate::isValid() const { return m_state != Invalid; }
@@ -422,11 +430,11 @@ QString QScriptValuePrivate::toString() const
case Invalid:
return QString();
case CBool:
- return m_number ? QString::fromLatin1("true") : QString::fromLatin1("false");
+ return u.m_bool ? QString::fromLatin1("true") : QString::fromLatin1("false");
case CString:
- return m_string;
+ return *u.m_string;
case CNumber:
- return QScriptConverter::toString(m_number);
+ return QScriptConverter::toString(u.m_number);
case CNull:
return QString::fromLatin1("null");
case CUndefined:
@@ -450,9 +458,9 @@ qsreal QScriptValuePrivate::toNumber() const
case JSObject:
return JSValueToNumber(*m_engine, *this, /* exception */ 0);
case CNumber:
- return m_number;
+ return u.m_number;
case CBool:
- return m_number ? 1 : 0;
+ return u.m_bool ? 1 : 0;
case CNull:
case Invalid:
return 0;
@@ -460,15 +468,15 @@ qsreal QScriptValuePrivate::toNumber() const
return qQNaN();
case CString:
bool ok;
- qsreal result = m_string.toDouble(&ok);
+ qsreal result = u.m_string->toDouble(&ok);
if (ok)
return result;
- result = m_string.toInt(&ok, 0); // Try other bases.
+ result = u.m_string->toInt(&ok, 0); // Try other bases.
if (ok)
return result;
- if (m_string == "Infinity" || m_string == "-Infinity")
+ if (*u.m_string == "Infinity" || *u.m_string == "-Infinity")
return qInf();
- return m_string.length() ? qQNaN() : 0;
+ return u.m_string->length() ? qQNaN() : 0;
}
Q_ASSERT_X(false, "toNumber()", "Not all states are included in the previous switch statement.");
@@ -484,15 +492,15 @@ bool QScriptValuePrivate::toBool() const
case JSObject:
return true;
case CNumber:
- return !(qIsNaN(m_number) || !m_number);
+ return !(qIsNaN(u.m_number) || !u.m_number);
case CBool:
- return m_number;
+ return u.m_bool;
case Invalid:
case CNull:
case CUndefined:
return false;
case CString:
- return m_string.length();
+ return u.m_string->length();
}
Q_ASSERT_X(false, "toBool()", "Not all states are included in the previous switch statement.");
@@ -551,23 +559,23 @@ QScriptValuePrivate* QScriptValuePrivate::toObject(QScriptEnginePrivate* engine)
case CString:
{
// Exception can't occur here.
- JSObjectRef object = JSValueToObject(*engine, engine->makeJSValue(m_string), /* exception */ 0);
+ JSObjectRef object = JSValueToObject(*engine, engine->makeJSValue(*u.m_string), /* exception */ 0);
Q_ASSERT(object);
- return new QScriptValuePrivate(engine, object, object);
+ return new QScriptValuePrivate(engine, object);
}
case CNumber:
{
// Exception can't occur here.
- JSObjectRef object = JSValueToObject(*engine, engine->makeJSValue(m_number), /* exception */ 0);
+ JSObjectRef object = JSValueToObject(*engine, engine->makeJSValue(u.m_number), /* exception */ 0);
Q_ASSERT(object);
- return new QScriptValuePrivate(engine, object, object);
+ return new QScriptValuePrivate(engine, object);
}
case CBool:
{
// Exception can't occure here.
- JSObjectRef object = JSValueToObject(*engine, engine->makeJSValue(static_cast<bool>(m_number)), /* exception */ 0);
+ JSObjectRef object = JSValueToObject(*engine, engine->makeJSValue(u.m_bool), /* exception */ 0);
Q_ASSERT(object);
- return new QScriptValuePrivate(engine, object, object);
+ return new QScriptValuePrivate(engine, object);
}
case JSValue:
if (refinedJSValue() != JSPrimitive)
@@ -605,6 +613,35 @@ QScriptValuePrivate* QScriptValuePrivate::toObject()
return new QScriptValuePrivate;
}
+inline QScriptValuePrivate* QScriptValuePrivate::prototype()
+{
+ if (isObject()) {
+ JSValueRef prototype = JSObjectGetPrototype(*m_engine, *this);
+ if (JSValueIsNull(*m_engine, prototype))
+ return new QScriptValuePrivate(engine(), prototype);
+ // The prototype could be either a null or a JSObject, so it is safe to cast the prototype
+ // to the JSObjectRef here.
+ return new QScriptValuePrivate(engine(), prototype, const_cast<JSObjectRef>(prototype));
+ }
+ return new QScriptValuePrivate;
+}
+
+inline void QScriptValuePrivate::setPrototype(QScriptValuePrivate* prototype)
+{
+ if (isObject() && prototype->isValid() && (prototype->isObject() || prototype->isNull())) {
+ if (engine() != prototype->engine()) {
+ qWarning("QScriptValue::setPrototype() failed: cannot set a prototype created in a different engine");
+ return;
+ }
+ // FIXME: This could be replaced by a new, faster API
+ // look at https://bugs.webkit.org/show_bug.cgi?id=40060
+ JSObjectSetPrototype(*m_engine, *this, *prototype);
+ JSValueRef proto = JSObjectGetPrototype(*m_engine, *this);
+ if (!JSValueIsStrictEqual(*m_engine, proto, *prototype))
+ qWarning("QScriptValue::setPrototype() failed: cyclic prototype value");
+ }
+}
+
bool QScriptValuePrivate::equals(QScriptValuePrivate* other)
{
if (!isValid())
@@ -615,9 +652,9 @@ bool QScriptValuePrivate::equals(QScriptValuePrivate* other)
if ((m_state == other->m_state) && !isJSBased()) {
if (isNumberBased())
- return m_number == other->m_number;
+ return u.m_number == other->u.m_number;
Q_ASSERT(isStringBased());
- return m_string == other->m_string;
+ return *u.m_string == *(other->u.m_string);
}
if (!isJSBased() && !other->isJSBased())
@@ -655,7 +692,7 @@ bool QScriptValuePrivate::strictlyEquals(QScriptValuePrivate* other)
}
if (isStringBased()) {
if (other->isStringBased())
- return m_string == other->m_string;
+ return *u.m_string == *(other->u.m_string);
if (other->isJSBased()) {
assignEngine(other->engine());
return JSValueIsStrictEqual(*m_engine, *this, *other);
@@ -663,7 +700,7 @@ bool QScriptValuePrivate::strictlyEquals(QScriptValuePrivate* other)
}
if (isNumberBased()) {
if (other->isNumberBased())
- return m_number == other->m_number;
+ return u.m_number == other->u.m_number;
if (other->isJSBased()) {
assignEngine(other->engine());
return JSValueIsStrictEqual(*m_engine, *this, *other);
@@ -690,13 +727,14 @@ bool QScriptValuePrivate::assignEngine(QScriptEnginePrivate* engine)
JSValueRef value;
switch (m_state) {
case CBool:
- value = engine->makeJSValue(static_cast<bool>(m_number));
+ value = engine->makeJSValue(u.m_bool);
break;
case CString:
- value = engine->makeJSValue(m_string);
+ value = engine->makeJSValue(*u.m_string);
+ delete u.m_string;
break;
case CNumber:
- value = engine->makeJSValue(m_number);
+ value = engine->makeJSValue(u.m_number);
break;
case CNull:
value = engine->makeJSValue(QScriptValue::NullValue);
@@ -713,7 +751,8 @@ bool QScriptValuePrivate::assignEngine(QScriptEnginePrivate* engine)
}
m_engine = engine;
m_state = JSPrimitive;
- setValue(value);
+ u.m_value = value;
+ JSValueProtect(*m_engine, value);
return true;
}
@@ -763,22 +802,15 @@ QScriptEnginePrivate* QScriptValuePrivate::engine() const
QScriptValuePrivate::operator JSValueRef() const
{
Q_ASSERT(isJSBased());
- return m_value;
+ Q_ASSERT(u.m_value);
+ return u.m_value;
}
QScriptValuePrivate::operator JSObjectRef() const
{
Q_ASSERT(m_state == JSObject);
- return m_object;
-}
-
-void QScriptValuePrivate::setValue(JSValueRef value)
-{
- if (m_value)
- JSValueUnprotect(*m_engine, m_value);
- if (value)
- JSValueProtect(*m_engine, value);
- m_value = value;
+ Q_ASSERT(u.m_object);
+ return u.m_object;
}
/*!
@@ -806,10 +838,9 @@ QScriptValuePrivate::State QScriptValuePrivate::refinedJSValue()
if (!JSValueIsObject(*m_engine, *this)) {
m_state = JSPrimitive;
} else {
+ // Difference between JSValueRef and JSObjectRef is only in their type, binarywise it is the same.
+ // As m_value and m_object are stored in the u union, it is enough to change the m_state only.
m_state = JSObject;
- // We are sure that value is an JSObject, so we can const_cast safely without
- // calling JSC C API (JSValueToObject(*m_engine, *this, /* exceptions */ 0)).
- m_object = const_cast<JSObjectRef>(m_value);
}
return m_state;
}
diff --git a/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.cpp b/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.cpp
index 90730c3..27d6df2 100644
--- a/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.cpp
+++ b/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.cpp
@@ -431,6 +431,46 @@ void tst_QScriptValue::call()
QVERIFY(incr.call().isValid()); // Exception.
}
+void tst_QScriptValue::getSetPrototype()
+{
+ QScriptEngine engine;
+ QScriptValue object = engine.evaluate("new Object()");
+ QScriptValue object2 = engine.evaluate("new Object()");
+ object2.setPrototype(object);
+ QCOMPARE(object2.prototype().strictlyEquals(object), true);
+
+ QScriptValue inv;
+ inv.setPrototype(object);
+ QCOMPARE(inv.prototype().isValid(), false);
+
+ QScriptEngine otherEngine;
+ QScriptValue object3 = otherEngine.evaluate("new Object()");
+ QTest::ignoreMessage(QtWarningMsg, "QScriptValue::setPrototype() failed: cannot set a prototype created in a different engine");
+ object2.setPrototype(object3);
+ QCOMPARE(object2.prototype().strictlyEquals(object), true);
+
+ // cyclic prototypes
+ {
+ QScriptValue ret = engine.evaluate("o = { }; p = { }; o.__proto__ = p; p.__proto__ = o");
+ QCOMPARE(ret.isError(), true);
+ QCOMPARE(ret.toString(), QLatin1String("Error: cyclic __proto__ value"));
+ }
+ {
+ QScriptValue ret = engine.evaluate("p.__proto__ = { }");
+ QCOMPARE(ret.isError(), false);
+ }
+
+ QScriptValue old = object.prototype();
+ QTest::ignoreMessage(QtWarningMsg, "QScriptValue::setPrototype() failed: cyclic prototype value");
+ object.setPrototype(object);
+ QCOMPARE(object.prototype().strictlyEquals(old), true);
+
+ object2.setPrototype(object);
+ QTest::ignoreMessage(QtWarningMsg, "QScriptValue::setPrototype() failed: cyclic prototype value");
+ object.setPrototype(object2);
+ QCOMPARE(object.prototype().strictlyEquals(old), true);
+}
+
void tst_QScriptValue::toObjectSimple()
{
QScriptEngine eng;
diff --git a/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.h b/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.h
index 0565b6f..f9fcedb 100644
--- a/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.h
+++ b/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.h
@@ -47,6 +47,7 @@ private slots:
void dataSharing();
void constructors_data();
void constructors();
+ void getSetPrototype();
void call();
void ctor();
void toObjectSimple();