1
0
mirror of https://github.com/robertkrimen/otto synced 2025-10-12 20:27:30 +08:00

Add Object.isExtensible & Object.preventExtensions...

...and fix the deep implementation of defineOwnProperty
so that they can work (more or less) properly
This commit is contained in:
Robert Krimen 2013-05-03 21:36:22 +02:00
parent 2e0fe63a64
commit 683e3956aa
4 changed files with 78 additions and 7 deletions

View File

@ -126,3 +126,21 @@ func builtinObject_create(call FunctionCall) Value {
return toValue(object)
}
func builtinObject_isExtensible(call FunctionCall) Value {
object := call.Argument(0)
if object := object._object(); object != nil {
return toValue(object.stash.extensible())
}
panic(newTypeError())
}
func builtinObject_preventExtensions(call FunctionCall) Value {
object := call.Argument(0)
if object := object._object(); object != nil {
object.stash.lock()
} else {
panic(newTypeError())
}
return object
}

View File

@ -175,6 +175,8 @@ func newContext() *_runtime {
"defineProperty", 3, builtinObject_defineProperty,
"defineProperties", 2, builtinObject_defineProperties,
"create", 2, builtinObject_create,
"isExtensible", -1, builtinObject_isExtensible,
"preventExtensions", -1, builtinObject_preventExtensions,
)
self.Global.Function = self.newGlobalFunction(
@ -669,7 +671,7 @@ func newContext() *_runtime {
"RegExp", builtinRegExp,
builtinNewRegExp,
self.Global.RegExpPrototype,
"toString", -0xff, builtinRegExp_toString,
"toString", -255, builtinRegExp_toString,
"exec", -1, builtinRegExp_exec,
"test", -1, builtinRegExp_test,
)
@ -832,7 +834,7 @@ func (runtime *_runtime) newNativeFunction(_nativeFunction _nativeFunction, leng
if 0 > length {
length *= -1
// TODO Achk... hack
if length == 0xff {
if length == 255 {
length = 0
}
prototype = false

View File

@ -196,7 +196,7 @@ func (self *_object) defineOwnProperty(name string, descriptor _property, throw
{
if !exists {
if !self.extensible() {
return false
goto Reject
}
self.stash.defineProperty(name, descriptor.value, descriptor.mode)
return true
@ -213,7 +213,7 @@ func (self *_object) defineOwnProperty(name string, descriptor _property, throw
configurable := property.configurable()
if !configurable {
if descriptor.configurable() {
return false
goto Reject
}
// Test that, if enumerable is set on the property descriptor, then it should
// be the same as the existing property
@ -237,22 +237,27 @@ func (self *_object) defineOwnProperty(name string, descriptor _property, throw
} else if isDataDescriptor && descriptor.isDataDescriptor() {
if !configurable {
if property.writable() != descriptor.writable() {
return false
goto Reject
} else if !sameValue(value, descriptor.value.(Value)) {
return false
goto Reject
}
}
} else {
if !configurable {
defineGetSet, _ := descriptor.value.(_propertyGetSet)
if getSet[0] != defineGetSet[0] || getSet[1] != defineGetSet[1] {
return false
goto Reject
}
}
}
self.stash.defineProperty(name, descriptor.value, descriptor.mode)
return true
}
Reject:
if throw {
panic(newTypeError())
}
return false
}
func (self *_object) hasOwnProperty(name string) bool {

View File

@ -62,3 +62,49 @@ func TestObject_toLocaleString(t *testing.T) {
object.toLocaleString();
`, "Nothing happens.")
}
func TestObject_isExtensible(t *testing.T) {
Terst(t)
test := runTest()
test(`raise:
Object.isExtensible();
`, "TypeError")
test(`raise:
Object.isExtensible({});
`, "true")
test(`Object.isExtensible.length`, "1")
test(`Object.isExtensible.prototype`, "undefined")
}
func TestObject_preventExtensions(t *testing.T) {
Terst(t)
test := runTest()
test(`raise:
Object.preventExtensions()
`, "TypeError")
test(`raise:
var abc = { def: true };
var ghi = Object.preventExtensions(abc);
[ ghi.def === true, Object.isExtensible(abc), Object.isExtensible(ghi) ];
`, "true,false,false")
test(`
var abc = new String();
var def = Object.isExtensible(abc);
Object.preventExtensions(abc);
var ghi = false;
try {
Object.defineProperty(abc, "0", { value: "~" });
} catch (err) {
ghi = err instanceof TypeError;
}
[ def, ghi, abc.hasOwnProperty("0"), typeof abc[0] ];
`, "true,true,false,undefined")
test(`Object.preventExtensions.length`, "1")
test(`Object.preventExtensions.prototype`, "undefined")
}