Skip to content

Commit

Permalink
Add testcases for on-demand .prototype
Browse files Browse the repository at this point in the history
  • Loading branch information
svaarala committed Apr 20, 2018
1 parent a28e0d7 commit 78ea49b
Show file tree
Hide file tree
Showing 4 changed files with 187 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*---
{
"custom": true
}
---*/

/*===
- Object.defineProperty() and .prototype
TypeError
number 321
number 123
TypeError
done
===*/

// Because the .prototype is intended to be writable, but configurable or
// enumerable, Object.defineProperty() should not allow modification of
// any attributes except: (1) to disable writable, (2) to update the value.
print('- Object.defineProperty() and .prototype');
try {
// This must fail because the (actually non-existent) .prototype is
// not configurable.
var X = function () {};
Object.defineProperty(X, 'prototype', { enumerable: true });
print('never here');
} catch (e) {
print(e.name);
}
try {
// This must succeed because the .prototype is writable.
var X = function () {};
Object.defineProperty(X, 'prototype', { value: 321 });
print(typeof X.prototype, X.prototype);
} catch (e) {
print(e);
}
try {
// Defining all attributes which are compatible with the virtualized
// existing ones -> must succeed.
var X = function () {};
Object.defineProperty(X, 'prototype', {
value: 123,
writable: true,
enumerable: false,
configurable: false
});
print(typeof X.prototype, X.prototype);
} catch (e) {
print(e);
}
try {
// Defining all attributes which are incompatible with the virtualized
// existing ones -> must fail.
var X = function () {};
Object.defineProperty(X, 'prototype', {
value: 123,
writable: true,
enumerable: true, // incompatible
configurable: false
});
print('never here');
} catch (e) {
print(e.name);
}

print('done');
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*---
{
"custom": true
}
---*/

/*===
- Object.getOwnPropertyDescriptor() spawns .prototype
object
object
true
false
false
done
===*/

print('- Object.getOwnPropertyDescriptor() spawns .prototype');
var X = function () {};
var pd = Object.getOwnPropertyDescriptor(X, 'prototype');
print(typeof pd);
print(typeof pd.value);
print(pd.writable);
print(pd.enumerable);
print(pd.configurable);

print('done');
23 changes: 23 additions & 0 deletions tests/ecmascript/test-dev-ondemand-constructor-prototype-misc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*---
{
"custom": true
}
---*/

print('- non-constructable built-ins have no .prototype');
var X = Math.cos;
print('prototype' in X);
print(X.prototype);
print('prototype' in X);

print('- non-constructable functions like object getter/setters have no .prototype');
var tmp = {
get X() {},
};
X = Object.getOwnPropertyDescriptor(tmp, 'X').get;
print(typeof X);
print('prototype' in X);
print(X.prototype);
print('prototype' in X);

print('done');
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*---
{
"custom": true
}
---*/

function FX() {
print('finalize X');
}
function FY() {
print('finalize Y');
}

print('- prototype in func');
var f = function () {};
print('prototype' in f);
Duktape.gc(); Duktape.gc();

print('- own property names');
var f = function () {};
print(Object.getOwnPropertyNames(f).join(','));
f.prototype.foo = 'bar';
print(Object.getOwnPropertyNames(f).join(','));
Duktape.gc(); Duktape.gc();

print('- refcount finalization, anonymous function');
var X = function () {};
Duktape.fin(X, FX);
print('setting X to null');
X = null;
print('X set to null');
Duktape.gc(); Duktape.gc();

print('- refcount finalization, named function');
var X = function foo() {};
Duktape.fin(X, FX);
print('setting X to null');
X = null;
print('X set to null');
Duktape.gc(); Duktape.gc();

print('- refcount finalization, anonymous inner function, reference not kept');
var X = function () {
var Y = function () {};
Duktape.fin(Y, FY);
Y = null;
};
Duktape.fin(X, FX);
print('call X');
X();
print('setting X to null');
X = null;
print('X set to null');
Duktape.gc(); Duktape.gc();

print('- refcount finalization, anonymous inner function, reference kept');
var X = function () {
var Y = function () {};
Duktape.fin(Y, FY);
// At this point the anonymous inner function points to the outer scope,
// which holds a reference back to the function via 'Y', so cannot
// collect via refcounting.
};
Duktape.fin(X, FX);
print('call X');
X();
print('setting X to null');
X = null;
print('X set to null');
Duktape.gc(); Duktape.gc();

print('done');

0 comments on commit 78ea49b

Please sign in to comment.