mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 492840 - ES5: Implement Object.create. r=mrbkap
This commit is contained in:
parent
9613c2771b
commit
49c30c2502
@ -2756,6 +2756,71 @@ obj_defineProperties(JSContext* cx, uintN argc, jsval* vp)
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
/* ES5 15.2.3.5: Object.create(O [, Properties]) */
|
||||
static JSBool
|
||||
obj_create(JSContext *cx, uintN argc, jsval *vp)
|
||||
{
|
||||
if (argc == 0) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_MORE_ARGS_NEEDED,
|
||||
"Object.create", "0", "s");
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
jsval v = vp[2];
|
||||
if (!JSVAL_IS_OBJECT(vp[2])) {
|
||||
char *bytes = js_DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, v, NULL);
|
||||
if (!bytes)
|
||||
return JS_FALSE;
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_UNEXPECTED_TYPE,
|
||||
bytes, "not an object or null");
|
||||
JS_free(cx, bytes);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* It's plausible that it's safe to just use the context's global object,
|
||||
* but since we're not completely sure, better safe than sorry.
|
||||
*/
|
||||
JSObject *obj =
|
||||
js_NewObjectWithGivenProto(cx, &js_ObjectClass, JSVAL_TO_OBJECT(v), JS_GetScopeChain(cx));
|
||||
if (!obj)
|
||||
return JS_FALSE;
|
||||
*vp = OBJECT_TO_JSVAL(obj); /* Root and prepare for eventual return. */
|
||||
|
||||
/* 15.2.3.5 step 4. */
|
||||
if (argc > 1 && vp[3] != JSVAL_VOID) {
|
||||
if (JSVAL_IS_PRIMITIVE(vp[3])) {
|
||||
js_ReportValueError(cx, JSMSG_NOT_NONNULL_OBJECT, -1, vp[3], NULL);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
JSObject *props = JSVAL_TO_OBJECT(vp[3]);
|
||||
JSAutoIdArray ida(cx, JS_Enumerate(cx, props));
|
||||
if (!ida)
|
||||
return JS_FALSE;
|
||||
|
||||
AutoDescriptorArray descs(cx);
|
||||
size_t len = ida.length();
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
PropertyDescriptor desc;
|
||||
jsid id = ida[i];
|
||||
if (!JS_GetPropertyById(cx, props, id, &vp[1]) || !desc.initialize(cx, id, vp[1]) ||
|
||||
!descs.append(desc)) {
|
||||
return JS_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
bool dummy;
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
if (!DefineProperty(cx, obj, descs[i], true, &dummy))
|
||||
return JS_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* 5. Return obj. */
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
|
||||
#if JS_HAS_OBJ_WATCHPOINT
|
||||
const char js_watch_str[] = "watch";
|
||||
@ -2807,6 +2872,7 @@ static JSFunctionSpec object_static_methods[] = {
|
||||
JS_FN("keys", obj_keys, 1,0),
|
||||
JS_FN("defineProperty", obj_defineProperty, 3,0),
|
||||
JS_FN("defineProperties", obj_defineProperties, 2,0),
|
||||
JS_FN("create", obj_create, 2,0),
|
||||
JS_FS_END
|
||||
};
|
||||
|
||||
|
52
js/src/tests/ecma_5/Object/15.2.3.5-01.js
Normal file
52
js/src/tests/ecma_5/Object/15.2.3.5-01.js
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/licenses/publicdomain/
|
||||
*/
|
||||
|
||||
var gTestfile = '15.2.3.5-01.js';
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = 492840;
|
||||
var summary = 'ES5 Object.create(O [, Properties])';
|
||||
|
||||
print(BUGNUMBER + ": " + summary);
|
||||
|
||||
/**************
|
||||
* BEGIN TEST *
|
||||
**************/
|
||||
|
||||
assertEq("create" in Object, true);
|
||||
assertEq(Object.create.length, 2);
|
||||
|
||||
var o, desc, props, proto;
|
||||
|
||||
o = Object.create(null);
|
||||
assertEq(Object.getPrototypeOf(o), null, "bad null-proto");
|
||||
|
||||
o = Object.create(null, { a: { value: 17, enumerable: false } });
|
||||
assertEq(Object.getPrototypeOf(o), null, "bad null-proto");
|
||||
assertEq("a" in o, true);
|
||||
desc = Object.getOwnPropertyDescriptor(o, "a");
|
||||
assertEq(desc !== undefined, true, "no descriptor?");
|
||||
assertEq(desc.value, 17);
|
||||
assertEq(desc.enumerable, false);
|
||||
assertEq(desc.configurable, false);
|
||||
assertEq(desc.writable, false);
|
||||
|
||||
props = Object.create({ bar: 15 });
|
||||
Object.defineProperty(props, "foo", { enumerable: false, value: 42 });
|
||||
proto = { baz: 12 };
|
||||
o = Object.create(proto, props);
|
||||
assertEq(Object.getPrototypeOf(o), proto);
|
||||
assertEq(Object.getOwnPropertyDescriptor(o, "foo"), undefined);
|
||||
assertEq("foo" in o, false);
|
||||
assertEq(Object.getOwnPropertyDescriptor(o, "bar"), undefined);
|
||||
assertEq("bar" in o, false);
|
||||
assertEq(Object.getOwnPropertyDescriptor(o, "baz"), undefined);
|
||||
assertEq(o.baz, 12);
|
||||
assertEq(o.hasOwnProperty("baz"), false);
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
reportCompare(true, true);
|
||||
|
||||
print("All tests passed!");
|
Loading…
Reference in New Issue
Block a user