From 99a706fa11c2009e2ed7db4df74b273bc1cdcd63 Mon Sep 17 00:00:00 2001 From: Dmitry Panov Date: Sun, 26 Apr 2020 13:25:22 +0100 Subject: [PATCH] Standard compliance fixes for Array, Error and Function --- builtin_array.go | 19 ++++----- builtin_error.go | 33 +++++++--------- builtin_function.go | 29 +++++++++++--- runtime.go | 5 ++- string.go | 1 + tc39_test.go | 94 ++++++++++++++++++++++++++++++--------------- 6 files changed, 115 insertions(+), 66 deletions(-) diff --git a/builtin_array.go b/builtin_array.go index 0fadea6a..b8d4b729 100644 --- a/builtin_array.go +++ b/builtin_array.go @@ -1226,15 +1226,16 @@ func (r *Runtime) createArrayProto(val *Object) objectImpl { o._putSym(symIterator, valueProp(valuesFunc, true, false, true)) - bl := r.NewObject() - bl.self.setOwnStr("copyWithin", valueTrue, true) - bl.self.setOwnStr("entries", valueTrue, true) - bl.self.setOwnStr("fill", valueTrue, true) - bl.self.setOwnStr("find", valueTrue, true) - bl.self.setOwnStr("findIndex", valueTrue, true) - bl.self.setOwnStr("keys", valueTrue, true) - bl.self.setOwnStr("values", valueTrue, true) - o._putSym(symUnscopables, valueProp(bl, false, false, true)) + bl := r.newBaseObject(nil, classObject) + bl.setOwnStr("copyWithin", valueTrue, true) + bl.setOwnStr("entries", valueTrue, true) + bl.setOwnStr("fill", valueTrue, true) + bl.setOwnStr("find", valueTrue, true) + bl.setOwnStr("findIndex", valueTrue, true) + bl.setOwnStr("includes", valueTrue, true) + bl.setOwnStr("keys", valueTrue, true) + bl.setOwnStr("values", valueTrue, true) + o._putSym(symUnscopables, valueProp(bl.val, false, false, true)) return o } diff --git a/builtin_error.go b/builtin_error.go index 0209931f..5880b88d 100644 --- a/builtin_error.go +++ b/builtin_error.go @@ -1,5 +1,12 @@ package goja +func (r *Runtime) createErrorPrototype(name valueString) *Object { + o := r.newBaseObject(r.global.ErrorPrototype, classObject) + o._putProp("message", stringEmpty, true, false, true) + o._putProp("name", name, true, false, true) + return o.val +} + func (r *Runtime) initErrors() { r.global.ErrorPrototype = r.NewObject() o := r.global.ErrorPrototype.self @@ -10,51 +17,39 @@ func (r *Runtime) initErrors() { r.global.Error = r.newNativeFuncConstruct(r.builtin_Error, "Error", r.global.ErrorPrototype, 1) r.addToGlobal("Error", r.global.Error) - r.global.TypeErrorPrototype = r.builtin_new(r.global.Error, []Value{}) - o = r.global.TypeErrorPrototype.self - o._putProp("name", stringTypeError, true, false, true) + r.global.TypeErrorPrototype = r.createErrorPrototype(stringTypeError) r.global.TypeError = r.newNativeFuncConstructProto(r.builtin_Error, "TypeError", r.global.TypeErrorPrototype, r.global.Error, 1) r.addToGlobal("TypeError", r.global.TypeError) - r.global.ReferenceErrorPrototype = r.builtin_new(r.global.Error, []Value{}) - o = r.global.ReferenceErrorPrototype.self - o._putProp("name", stringReferenceError, true, false, true) + r.global.ReferenceErrorPrototype = r.createErrorPrototype(stringReferenceError) r.global.ReferenceError = r.newNativeFuncConstructProto(r.builtin_Error, "ReferenceError", r.global.ReferenceErrorPrototype, r.global.Error, 1) r.addToGlobal("ReferenceError", r.global.ReferenceError) - r.global.SyntaxErrorPrototype = r.builtin_new(r.global.Error, []Value{}) - o = r.global.SyntaxErrorPrototype.self - o._putProp("name", stringSyntaxError, true, false, true) + r.global.SyntaxErrorPrototype = r.createErrorPrototype(stringSyntaxError) r.global.SyntaxError = r.newNativeFuncConstructProto(r.builtin_Error, "SyntaxError", r.global.SyntaxErrorPrototype, r.global.Error, 1) r.addToGlobal("SyntaxError", r.global.SyntaxError) - r.global.RangeErrorPrototype = r.builtin_new(r.global.Error, []Value{}) - o = r.global.RangeErrorPrototype.self - o._putProp("name", stringRangeError, true, false, true) + r.global.RangeErrorPrototype = r.createErrorPrototype(stringRangeError) r.global.RangeError = r.newNativeFuncConstructProto(r.builtin_Error, "RangeError", r.global.RangeErrorPrototype, r.global.Error, 1) r.addToGlobal("RangeError", r.global.RangeError) - r.global.EvalErrorPrototype = r.builtin_new(r.global.Error, []Value{}) + r.global.EvalErrorPrototype = r.createErrorPrototype(stringEvalError) o = r.global.EvalErrorPrototype.self o._putProp("name", stringEvalError, true, false, true) r.global.EvalError = r.newNativeFuncConstructProto(r.builtin_Error, "EvalError", r.global.EvalErrorPrototype, r.global.Error, 1) r.addToGlobal("EvalError", r.global.EvalError) - r.global.URIErrorPrototype = r.builtin_new(r.global.Error, []Value{}) - o = r.global.URIErrorPrototype.self - o._putProp("name", stringURIError, true, false, true) + r.global.URIErrorPrototype = r.createErrorPrototype(stringURIError) r.global.URIError = r.newNativeFuncConstructProto(r.builtin_Error, "URIError", r.global.URIErrorPrototype, r.global.Error, 1) r.addToGlobal("URIError", r.global.URIError) - r.global.GoErrorPrototype = r.builtin_new(r.global.Error, []Value{}) - o = r.global.GoErrorPrototype.self - o._putProp("name", stringGoError, true, false, true) + r.global.GoErrorPrototype = r.createErrorPrototype(stringGoError) r.global.GoError = r.newNativeFuncConstructProto(r.builtin_Error, "GoError", r.global.GoErrorPrototype, r.global.Error, 1) r.addToGlobal("GoError", r.global.GoError) diff --git a/builtin_function.go b/builtin_function.go index 7cc45f79..249e29bd 100644 --- a/builtin_function.go +++ b/builtin_function.go @@ -59,6 +59,16 @@ repeat: return nil } +func (r *Runtime) functionproto_hasInstance(call FunctionCall) Value { + if o, ok := call.This.(*Object); ok { + if _, ok = o.self.assertCallable(); ok { + return r.toBoolean(o.self.hasInstance(call.Argument(0))) + } + } + + return valueFalse +} + func (r *Runtime) createListFromArrayLike(a Value) []Value { o := r.toObject(a) if arr := r.checkStdArrayObj(o); arr != nil { @@ -145,9 +155,15 @@ func (r *Runtime) functionproto_bind(call FunctionCall) Value { l = 0 } + name := obj.self.getStr("name", nil) + nameStr := stringBound_ + if s, ok := name.(valueString); ok { + nameStr = nameStr.concat(s) + } + v := &Object{runtime: r} - ff := r.newNativeFuncObj(v, r.boundCallable(fcall, call.Arguments), r.boundConstruct(construct, call.Arguments), "", nil, l) + ff := r.newNativeFuncObj(v, r.boundCallable(fcall, call.Arguments), r.boundConstruct(construct, call.Arguments), nameStr.string(), nil, l) v.self = &boundFuncObject{ nativeFuncObject: *ff, wrapped: obj, @@ -161,12 +177,15 @@ func (r *Runtime) functionproto_bind(call FunctionCall) Value { } func (r *Runtime) initFunction() { - o := r.global.FunctionPrototype.self - o.(*nativeFuncObject).prototype = r.global.ObjectPrototype - o._putProp("toString", r.newNativeFunc(r.functionproto_toString, nil, "toString", nil, 0), true, false, true) + o := r.global.FunctionPrototype.self.(*nativeFuncObject) + o.prototype = r.global.ObjectPrototype + o.nameProp.value = stringEmpty + o._putProp("apply", r.newNativeFunc(r.functionproto_apply, nil, "apply", nil, 2), true, false, true) - o._putProp("call", r.newNativeFunc(r.functionproto_call, nil, "call", nil, 1), true, false, true) o._putProp("bind", r.newNativeFunc(r.functionproto_bind, nil, "bind", nil, 1), true, false, true) + o._putProp("call", r.newNativeFunc(r.functionproto_call, nil, "call", nil, 1), true, false, true) + o._putProp("toString", r.newNativeFunc(r.functionproto_toString, nil, "toString", nil, 0), true, false, true) + o._putSym(symHasInstance, valueProp(r.newNativeFunc(r.functionproto_hasInstance, nil, "[Symbol.hasInstance]", nil, 1), false, false, false)) r.global.Function = r.newNativeFuncConstruct(r.builtin_Function, "Function", r.global.FunctionPrototype, 1) r.addToGlobal("Function", r.global.Function) diff --git a/runtime.go b/runtime.go index 9fa55f43..55657c40 100644 --- a/runtime.go +++ b/runtime.go @@ -334,7 +334,10 @@ func (r *Runtime) init() { } r.vm.init() - r.global.FunctionPrototype = r.newNativeFunc(nil, nil, "Empty", nil, 0) + r.global.FunctionPrototype = r.newNativeFunc(func(FunctionCall) Value { + return _undefined + }, nil, " ", nil, 0) + r.global.IteratorPrototype = r.newLazyObject(r.createIterProto) r.initObject() diff --git a/string.go b/string.go index f1e42022..4f600e15 100644 --- a/string.go +++ b/string.go @@ -29,6 +29,7 @@ var ( stringInfinity = asciiString("Infinity") stringPlusInfinity = asciiString("+Infinity") stringNegInfinity = asciiString("-Infinity") + stringBound_ valueString = asciiString("bound ") stringEmpty valueString = asciiString("") stringError valueString = asciiString("Error") diff --git a/tc39_test.go b/tc39_test.go index 017c34e1..ebf046a7 100644 --- a/tc39_test.go +++ b/tc39_test.go @@ -40,31 +40,62 @@ var ( "test/annexB/built-ins/escape/escape-above-astral.js": true, // \u{xxxxx} // class - "test/language/statements/class/subclass/builtin-objects/Symbol/symbol-valid-as-extends-value.js": true, - "test/language/statements/class/subclass/builtin-objects/Symbol/new-symbol-with-super-throws.js": true, - "test/language/statements/class/subclass/builtin-objects/WeakSet/super-must-be-called.js": true, - "test/language/statements/class/subclass/builtin-objects/WeakSet/regular-subclassing.js": true, - "test/language/statements/class/subclass/builtin-objects/WeakMap/super-must-be-called.js": true, - "test/language/statements/class/subclass/builtin-objects/WeakMap/regular-subclassing.js": true, - "test/language/statements/class/subclass/builtin-objects/Map/super-must-be-called.js": true, - "test/language/statements/class/subclass/builtin-objects/Map/regular-subclassing.js": true, - "test/language/statements/class/subclass/builtin-objects/Set/super-must-be-called.js": true, - "test/language/statements/class/subclass/builtin-objects/Set/regular-subclassing.js": true, - "test/language/statements/class/subclass/builtin-objects/Object/replacing-prototype.js": true, - "test/language/statements/class/subclass/builtin-objects/Object/regular-subclassing.js": true, - "test/built-ins/Array/prototype/concat/Array.prototype.concat_non-array.js": true, - "test/language/statements/class/subclass/builtin-objects/Array/length.js": true, - "test/language/statements/class/subclass/builtin-objects/TypedArray/super-must-be-called.js": true, - "test/language/statements/class/subclass/builtin-objects/TypedArray/regular-subclassing.js": true, - "test/language/statements/class/subclass/builtin-objects/DataView/super-must-be-called.js": true, - "test/language/statements/class/subclass/builtin-objects/DataView/regular-subclassing.js": true, - "test/language/statements/class/subclass/builtin-objects/String/super-must-be-called.js": true, - "test/language/statements/class/subclass/builtin-objects/String/regular-subclassing.js": true, - "test/language/statements/class/subclass/builtin-objects/String/length.js": true, - "test/language/statements/class/subclass/builtin-objects/Date/super-must-be-called.js": true, - "test/language/statements/class/subclass/builtin-objects/Date/regular-subclassing.js": true, - "test/language/statements/class/subclass/builtin-objects/Number/super-must-be-called.js": true, - "test/language/statements/class/subclass/builtin-objects/Number/regular-subclassing.js": true, + "test/language/statements/class/subclass/builtin-objects/Symbol/symbol-valid-as-extends-value.js": true, + "test/language/statements/class/subclass/builtin-objects/Symbol/new-symbol-with-super-throws.js": true, + "test/language/statements/class/subclass/builtin-objects/WeakSet/super-must-be-called.js": true, + "test/language/statements/class/subclass/builtin-objects/WeakSet/regular-subclassing.js": true, + "test/language/statements/class/subclass/builtin-objects/WeakMap/super-must-be-called.js": true, + "test/language/statements/class/subclass/builtin-objects/WeakMap/regular-subclassing.js": true, + "test/language/statements/class/subclass/builtin-objects/Map/super-must-be-called.js": true, + "test/language/statements/class/subclass/builtin-objects/Map/regular-subclassing.js": true, + "test/language/statements/class/subclass/builtin-objects/Set/super-must-be-called.js": true, + "test/language/statements/class/subclass/builtin-objects/Set/regular-subclassing.js": true, + "test/language/statements/class/subclass/builtin-objects/Object/replacing-prototype.js": true, + "test/language/statements/class/subclass/builtin-objects/Object/regular-subclassing.js": true, + "test/built-ins/Array/prototype/concat/Array.prototype.concat_non-array.js": true, + "test/language/statements/class/subclass/builtin-objects/Array/length.js": true, + "test/language/statements/class/subclass/builtin-objects/TypedArray/super-must-be-called.js": true, + "test/language/statements/class/subclass/builtin-objects/TypedArray/regular-subclassing.js": true, + "test/language/statements/class/subclass/builtin-objects/DataView/super-must-be-called.js": true, + "test/language/statements/class/subclass/builtin-objects/DataView/regular-subclassing.js": true, + "test/language/statements/class/subclass/builtin-objects/String/super-must-be-called.js": true, + "test/language/statements/class/subclass/builtin-objects/String/regular-subclassing.js": true, + "test/language/statements/class/subclass/builtin-objects/String/length.js": true, + "test/language/statements/class/subclass/builtin-objects/Date/super-must-be-called.js": true, + "test/language/statements/class/subclass/builtin-objects/Date/regular-subclassing.js": true, + "test/language/statements/class/subclass/builtin-objects/Number/super-must-be-called.js": true, + "test/language/statements/class/subclass/builtin-objects/Number/regular-subclassing.js": true, + "test/language/statements/class/subclass/builtin-objects/Function/super-must-be-called.js": true, + "test/language/statements/class/subclass/builtin-objects/Function/regular-subclassing.js": true, + "test/language/statements/class/subclass/builtin-objects/Function/instance-name.js": true, + "test/language/statements/class/subclass/builtin-objects/Function/instance-length.js": true, + "test/language/statements/class/subclass/builtin-objects/Boolean/super-must-be-called.js": true, + "test/language/statements/class/subclass/builtin-objects/Boolean/regular-subclassing.js": true, + "test/language/statements/class/subclass/builtin-objects/NativeError/URIError-super.js": true, + "test/language/statements/class/subclass/builtin-objects/NativeError/URIError-name.js": true, + "test/language/statements/class/subclass/builtin-objects/NativeError/URIError-message.js": true, + "test/language/statements/class/subclass/builtin-objects/NativeError/TypeError-super.js": true, + "test/language/statements/class/subclass/builtin-objects/NativeError/TypeError-name.js": true, + "test/language/statements/class/subclass/builtin-objects/NativeError/TypeError-message.js": true, + "test/language/statements/class/subclass/builtin-objects/NativeError/SyntaxError-super.js": true, + "test/language/statements/class/subclass/builtin-objects/NativeError/SyntaxError-name.js": true, + "test/language/statements/class/subclass/builtin-objects/NativeError/SyntaxError-message.js": true, + "test/language/statements/class/subclass/builtin-objects/NativeError/ReferenceError-super.js": true, + "test/language/statements/class/subclass/builtin-objects/NativeError/ReferenceError-name.js": true, + "test/language/statements/class/subclass/builtin-objects/NativeError/ReferenceError-message.js": true, + "test/language/statements/class/subclass/builtin-objects/NativeError/RangeError-super.js": true, + "test/language/statements/class/subclass/builtin-objects/NativeError/RangeError-name.js": true, + "test/language/statements/class/subclass/builtin-objects/NativeError/RangeError-message.js": true, + "test/language/statements/class/subclass/builtin-objects/NativeError/EvalError-super.js": true, + "test/language/statements/class/subclass/builtin-objects/NativeError/EvalError-name.js": true, + "test/language/statements/class/subclass/builtin-objects/NativeError/EvalError-message.js": true, + "test/language/statements/class/subclass/builtin-objects/Error/super-must-be-called.js": true, + "test/language/statements/class/subclass/builtin-objects/Error/regular-subclassing.js": true, + "test/language/statements/class/subclass/builtin-objects/Error/message-property-assignment.js": true, + "test/language/statements/class/subclass/builtin-objects/Array/super-must-be-called.js": true, + "test/language/statements/class/subclass/builtin-objects/Array/regular-subclassing.js": true, + "test/language/statements/class/subclass/builtin-objects/Array/contructor-calls-super-single-argument.js": true, + "test/language/statements/class/subclass/builtin-objects/Array/contructor-calls-super-multiple-arguments.js": true, // full unicode regexp flag "test/built-ins/RegExp/prototype/Symbol.match/u-advance-after-empty.js": true, @@ -109,17 +140,16 @@ var ( "12.9.3", "12.9.4", "19.1", + "19.2", + "19.3", "19.4", + "19.5", "20.1", "20.2", "20.3", "21.1", "21.2.5.6", - "22.1.2.1", - "22.1.2.3", - "22.1.2.5", - "22.1.3", - "22.1.4", + "22.1", "22.2", "23.1", "23.2", @@ -134,9 +164,9 @@ var ( } esIdPrefixWhiteList = []string{ - "sec-array.prototype.includes", + "sec-array", "sec-%typedarray%", - "sec-string.prototype", + "sec-string", "sec-date", "sec-number", "sec-math",