Browse Source

Avoid calling toString() (which itself may throw) when formatting error messages. Fixes #343

Dmitry Panov 3 years ago
parent
commit
51b65454fa
11 changed files with 104 additions and 82 deletions
  1. 1 1
      builtin_array.go
  2. 8 8
      builtin_map.go
  3. 1 1
      builtin_promise.go
  4. 9 10
      builtin_regexp.go
  5. 7 7
      builtin_set.go
  6. 1 1
      builtin_string.go
  7. 46 46
      builtin_typedarrays.go
  8. 20 0
      builtin_typedarrays_test.go
  9. 4 4
      builtin_weakmap.go
  10. 3 3
      builtin_weakset.go
  11. 4 1
      object.go

+ 1 - 1
builtin_array.go

@@ -1284,7 +1284,7 @@ func (r *Runtime) arrayIterProto_next(call FunctionCall) Value {
 	if iter, ok := thisObj.self.(*arrayIterObject); ok {
 		return iter.next()
 	}
-	panic(r.NewTypeError("Method Array Iterator.prototype.next called on incompatible receiver %s", thisObj.String()))
+	panic(r.NewTypeError("Method Array Iterator.prototype.next called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: thisObj})))
 }
 
 func (r *Runtime) createArrayProto(val *Object) objectImpl {

+ 8 - 8
builtin_map.go

@@ -44,7 +44,7 @@ func (r *Runtime) mapProto_clear(call FunctionCall) Value {
 	thisObj := r.toObject(call.This)
 	mo, ok := thisObj.self.(*mapObject)
 	if !ok {
-		panic(r.NewTypeError("Method Map.prototype.clear called on incompatible receiver %s", thisObj.String()))
+		panic(r.NewTypeError("Method Map.prototype.clear called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: thisObj})))
 	}
 
 	mo.m.clear()
@@ -56,7 +56,7 @@ func (r *Runtime) mapProto_delete(call FunctionCall) Value {
 	thisObj := r.toObject(call.This)
 	mo, ok := thisObj.self.(*mapObject)
 	if !ok {
-		panic(r.NewTypeError("Method Map.prototype.delete called on incompatible receiver %s", thisObj.String()))
+		panic(r.NewTypeError("Method Map.prototype.delete called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: thisObj})))
 	}
 
 	return r.toBoolean(mo.m.remove(call.Argument(0)))
@@ -66,7 +66,7 @@ func (r *Runtime) mapProto_get(call FunctionCall) Value {
 	thisObj := r.toObject(call.This)
 	mo, ok := thisObj.self.(*mapObject)
 	if !ok {
-		panic(r.NewTypeError("Method Map.prototype.get called on incompatible receiver %s", thisObj.String()))
+		panic(r.NewTypeError("Method Map.prototype.get called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: thisObj})))
 	}
 
 	return nilSafe(mo.m.get(call.Argument(0)))
@@ -76,7 +76,7 @@ func (r *Runtime) mapProto_has(call FunctionCall) Value {
 	thisObj := r.toObject(call.This)
 	mo, ok := thisObj.self.(*mapObject)
 	if !ok {
-		panic(r.NewTypeError("Method Map.prototype.has called on incompatible receiver %s", thisObj.String()))
+		panic(r.NewTypeError("Method Map.prototype.has called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: thisObj})))
 	}
 	if mo.m.has(call.Argument(0)) {
 		return valueTrue
@@ -88,7 +88,7 @@ func (r *Runtime) mapProto_set(call FunctionCall) Value {
 	thisObj := r.toObject(call.This)
 	mo, ok := thisObj.self.(*mapObject)
 	if !ok {
-		panic(r.NewTypeError("Method Map.prototype.set called on incompatible receiver %s", thisObj.String()))
+		panic(r.NewTypeError("Method Map.prototype.set called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: thisObj})))
 	}
 	mo.m.set(call.Argument(0), call.Argument(1))
 	return call.This
@@ -102,7 +102,7 @@ func (r *Runtime) mapProto_forEach(call FunctionCall) Value {
 	thisObj := r.toObject(call.This)
 	mo, ok := thisObj.self.(*mapObject)
 	if !ok {
-		panic(r.NewTypeError("Method Map.prototype.forEach called on incompatible receiver %s", thisObj.String()))
+		panic(r.NewTypeError("Method Map.prototype.forEach called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: thisObj})))
 	}
 	callbackFn, ok := r.toObject(call.Argument(0)).self.assertCallable()
 	if !ok {
@@ -133,7 +133,7 @@ func (r *Runtime) mapProto_getSize(call FunctionCall) Value {
 	thisObj := r.toObject(call.This)
 	mo, ok := thisObj.self.(*mapObject)
 	if !ok {
-		panic(r.NewTypeError("Method get Map.prototype.size called on incompatible receiver %s", thisObj.String()))
+		panic(r.NewTypeError("Method get Map.prototype.size called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: thisObj})))
 	}
 	return intToValue(int64(mo.m.size))
 }
@@ -210,7 +210,7 @@ func (r *Runtime) mapIterProto_next(call FunctionCall) Value {
 	if iter, ok := thisObj.self.(*mapIterObject); ok {
 		return iter.next()
 	}
-	panic(r.NewTypeError("Method Map Iterator.prototype.next called on incompatible receiver %s", thisObj.String()))
+	panic(r.NewTypeError("Method Map Iterator.prototype.next called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: thisObj})))
 }
 
 func (r *Runtime) createMapProto(val *Object) objectImpl {

+ 1 - 1
builtin_promise.go

@@ -244,7 +244,7 @@ func (r *Runtime) promiseProto_then(call FunctionCall) Value {
 		resultCapability := r.newPromiseCapability(c)
 		return r.performPromiseThen(p, call.Argument(0), call.Argument(1), resultCapability)
 	}
-	panic(r.NewTypeError("Method Promise.prototype.then called on incompatible receiver %s", thisObj))
+	panic(r.NewTypeError("Method Promise.prototype.then called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: thisObj})))
 }
 
 func (r *Runtime) newPromiseCapability(c *Object) *promiseCapability {

+ 9 - 10
builtin_regexp.go

@@ -386,14 +386,14 @@ func (r *Runtime) regexpproto_compile(call FunctionCall) Value {
 		return call.This
 	}
 
-	panic(r.NewTypeError("Method RegExp.prototype.compile called on incompatible receiver %s", call.This.toString()))
+	panic(r.NewTypeError("Method RegExp.prototype.compile called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: call.This})))
 }
 
 func (r *Runtime) regexpproto_exec(call FunctionCall) Value {
 	if this, ok := r.toObject(call.This).self.(*regexpObject); ok {
 		return this.exec(call.Argument(0).toString())
 	} else {
-		r.typeErrorResult(true, "Method RegExp.prototype.exec called on incompatible receiver %s", call.This.toString())
+		r.typeErrorResult(true, "Method RegExp.prototype.exec called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: call.This}))
 		return nil
 	}
 }
@@ -406,8 +406,7 @@ func (r *Runtime) regexpproto_test(call FunctionCall) Value {
 			return valueFalse
 		}
 	} else {
-		r.typeErrorResult(true, "Method RegExp.prototype.test called on incompatible receiver %s", call.This.toString())
-		return nil
+		panic(r.NewTypeError("Method RegExp.prototype.test called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: call.This})))
 	}
 }
 
@@ -518,7 +517,7 @@ func (r *Runtime) regexpproto_getGlobal(call FunctionCall) Value {
 	} else if call.This == r.global.RegExpPrototype {
 		return _undefined
 	} else {
-		panic(r.NewTypeError("Method RegExp.prototype.global getter called on incompatible receiver %s", call.This.toString()))
+		panic(r.NewTypeError("Method RegExp.prototype.global getter called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: call.This})))
 	}
 }
 
@@ -532,7 +531,7 @@ func (r *Runtime) regexpproto_getMultiline(call FunctionCall) Value {
 	} else if call.This == r.global.RegExpPrototype {
 		return _undefined
 	} else {
-		panic(r.NewTypeError("Method RegExp.prototype.multiline getter called on incompatible receiver %s", call.This.toString()))
+		panic(r.NewTypeError("Method RegExp.prototype.multiline getter called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: call.This})))
 	}
 }
 
@@ -546,7 +545,7 @@ func (r *Runtime) regexpproto_getIgnoreCase(call FunctionCall) Value {
 	} else if call.This == r.global.RegExpPrototype {
 		return _undefined
 	} else {
-		panic(r.NewTypeError("Method RegExp.prototype.ignoreCase getter called on incompatible receiver %s", call.This.toString()))
+		panic(r.NewTypeError("Method RegExp.prototype.ignoreCase getter called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: call.This})))
 	}
 }
 
@@ -560,7 +559,7 @@ func (r *Runtime) regexpproto_getUnicode(call FunctionCall) Value {
 	} else if call.This == r.global.RegExpPrototype {
 		return _undefined
 	} else {
-		panic(r.NewTypeError("Method RegExp.prototype.unicode getter called on incompatible receiver %s", call.This.toString()))
+		panic(r.NewTypeError("Method RegExp.prototype.unicode getter called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: call.This})))
 	}
 }
 
@@ -574,7 +573,7 @@ func (r *Runtime) regexpproto_getSticky(call FunctionCall) Value {
 	} else if call.This == r.global.RegExpPrototype {
 		return _undefined
 	} else {
-		panic(r.NewTypeError("Method RegExp.prototype.sticky getter called on incompatible receiver %s", call.This.toString()))
+		panic(r.NewTypeError("Method RegExp.prototype.sticky getter called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: call.This})))
 	}
 }
 
@@ -1206,7 +1205,7 @@ func (r *Runtime) regExpStringIteratorProto_next(call FunctionCall) Value {
 	if iter, ok := thisObj.self.(*regExpStringIterObject); ok {
 		return iter.next()
 	}
-	panic(r.NewTypeError("Method RegExp String Iterator.prototype.next called on incompatible receiver %s", thisObj.String()))
+	panic(r.NewTypeError("Method RegExp String Iterator.prototype.next called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: thisObj})))
 }
 
 func (r *Runtime) createRegExpStringIteratorPrototype(val *Object) objectImpl {

+ 7 - 7
builtin_set.go

@@ -42,7 +42,7 @@ func (r *Runtime) setProto_add(call FunctionCall) Value {
 	thisObj := r.toObject(call.This)
 	so, ok := thisObj.self.(*setObject)
 	if !ok {
-		panic(r.NewTypeError("Method Set.prototype.add called on incompatible receiver %s", thisObj.String()))
+		panic(r.NewTypeError("Method Set.prototype.add called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: thisObj})))
 	}
 
 	so.m.set(call.Argument(0), nil)
@@ -53,7 +53,7 @@ func (r *Runtime) setProto_clear(call FunctionCall) Value {
 	thisObj := r.toObject(call.This)
 	so, ok := thisObj.self.(*setObject)
 	if !ok {
-		panic(r.NewTypeError("Method Set.prototype.clear called on incompatible receiver %s", thisObj.String()))
+		panic(r.NewTypeError("Method Set.prototype.clear called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: thisObj})))
 	}
 
 	so.m.clear()
@@ -64,7 +64,7 @@ func (r *Runtime) setProto_delete(call FunctionCall) Value {
 	thisObj := r.toObject(call.This)
 	so, ok := thisObj.self.(*setObject)
 	if !ok {
-		panic(r.NewTypeError("Method Set.prototype.delete called on incompatible receiver %s", thisObj.String()))
+		panic(r.NewTypeError("Method Set.prototype.delete called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: thisObj})))
 	}
 
 	return r.toBoolean(so.m.remove(call.Argument(0)))
@@ -78,7 +78,7 @@ func (r *Runtime) setProto_forEach(call FunctionCall) Value {
 	thisObj := r.toObject(call.This)
 	so, ok := thisObj.self.(*setObject)
 	if !ok {
-		panic(r.NewTypeError("Method Set.prototype.forEach called on incompatible receiver %s", thisObj.String()))
+		panic(r.NewTypeError("Method Set.prototype.forEach called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: thisObj})))
 	}
 	callbackFn, ok := r.toObject(call.Argument(0)).self.assertCallable()
 	if !ok {
@@ -101,7 +101,7 @@ func (r *Runtime) setProto_has(call FunctionCall) Value {
 	thisObj := r.toObject(call.This)
 	so, ok := thisObj.self.(*setObject)
 	if !ok {
-		panic(r.NewTypeError("Method Set.prototype.has called on incompatible receiver %s", thisObj.String()))
+		panic(r.NewTypeError("Method Set.prototype.has called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: thisObj})))
 	}
 
 	return r.toBoolean(so.m.has(call.Argument(0)))
@@ -111,7 +111,7 @@ func (r *Runtime) setProto_getSize(call FunctionCall) Value {
 	thisObj := r.toObject(call.This)
 	so, ok := thisObj.self.(*setObject)
 	if !ok {
-		panic(r.NewTypeError("Method get Set.prototype.size called on incompatible receiver %s", thisObj.String()))
+		panic(r.NewTypeError("Method get Set.prototype.size called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: thisObj})))
 	}
 
 	return intToValue(int64(so.m.size))
@@ -185,7 +185,7 @@ func (r *Runtime) setIterProto_next(call FunctionCall) Value {
 	if iter, ok := thisObj.self.(*setIterObject); ok {
 		return iter.next()
 	}
-	panic(r.NewTypeError("Method Set Iterator.prototype.next called on incompatible receiver %s", thisObj.String()))
+	panic(r.NewTypeError("Method Set Iterator.prototype.next called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: thisObj})))
 }
 
 func (r *Runtime) createSetProto(val *Object) objectImpl {

+ 1 - 1
builtin_string.go

@@ -930,7 +930,7 @@ func (r *Runtime) stringIterProto_next(call FunctionCall) Value {
 	if iter, ok := thisObj.self.(*stringIterObject); ok {
 		return iter.next()
 	}
-	panic(r.NewTypeError("Method String Iterator.prototype.next called on incompatible receiver %s", thisObj.String()))
+	panic(r.NewTypeError("Method String Iterator.prototype.next called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: thisObj})))
 }
 
 func (r *Runtime) createStringIterProto(val *Object) objectImpl {

+ 46 - 46
builtin_typedarrays.go

@@ -197,7 +197,7 @@ func (r *Runtime) dataViewProto_getBuffer(call FunctionCall) Value {
 	if dv, ok := r.toObject(call.This).self.(*dataViewObject); ok {
 		return dv.viewedArrayBuf.val
 	}
-	panic(r.NewTypeError("Method get DataView.prototype.buffer called on incompatible receiver %s", call.This.String()))
+	panic(r.NewTypeError("Method get DataView.prototype.buffer called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: call.This})))
 }
 
 func (r *Runtime) dataViewProto_getByteLen(call FunctionCall) Value {
@@ -205,7 +205,7 @@ func (r *Runtime) dataViewProto_getByteLen(call FunctionCall) Value {
 		dv.viewedArrayBuf.ensureNotDetached(true)
 		return intToValue(int64(dv.byteLen))
 	}
-	panic(r.NewTypeError("Method get DataView.prototype.byteLength called on incompatible receiver %s", call.This.String()))
+	panic(r.NewTypeError("Method get DataView.prototype.byteLength called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: call.This})))
 }
 
 func (r *Runtime) dataViewProto_getByteOffset(call FunctionCall) Value {
@@ -213,21 +213,21 @@ func (r *Runtime) dataViewProto_getByteOffset(call FunctionCall) Value {
 		dv.viewedArrayBuf.ensureNotDetached(true)
 		return intToValue(int64(dv.byteOffset))
 	}
-	panic(r.NewTypeError("Method get DataView.prototype.byteOffset called on incompatible receiver %s", call.This.String()))
+	panic(r.NewTypeError("Method get DataView.prototype.byteOffset called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: call.This})))
 }
 
 func (r *Runtime) dataViewProto_getFloat32(call FunctionCall) Value {
 	if dv, ok := r.toObject(call.This).self.(*dataViewObject); ok {
 		return floatToValue(float64(dv.viewedArrayBuf.getFloat32(dv.getIdxAndByteOrder(r.toIndex(call.Argument(0)), call.Argument(1), 4))))
 	}
-	panic(r.NewTypeError("Method DataView.prototype.getFloat32 called on incompatible receiver %s", call.This.String()))
+	panic(r.NewTypeError("Method DataView.prototype.getFloat32 called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: call.This})))
 }
 
 func (r *Runtime) dataViewProto_getFloat64(call FunctionCall) Value {
 	if dv, ok := r.toObject(call.This).self.(*dataViewObject); ok {
 		return floatToValue(dv.viewedArrayBuf.getFloat64(dv.getIdxAndByteOrder(r.toIndex(call.Argument(0)), call.Argument(1), 8)))
 	}
-	panic(r.NewTypeError("Method DataView.prototype.getFloat64 called on incompatible receiver %s", call.This.String()))
+	panic(r.NewTypeError("Method DataView.prototype.getFloat64 called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: call.This})))
 }
 
 func (r *Runtime) dataViewProto_getInt8(call FunctionCall) Value {
@@ -235,21 +235,21 @@ func (r *Runtime) dataViewProto_getInt8(call FunctionCall) Value {
 		idx, _ := dv.getIdxAndByteOrder(r.toIndex(call.Argument(0)), call.Argument(1), 1)
 		return intToValue(int64(dv.viewedArrayBuf.getInt8(idx)))
 	}
-	panic(r.NewTypeError("Method DataView.prototype.getInt8 called on incompatible receiver %s", call.This.String()))
+	panic(r.NewTypeError("Method DataView.prototype.getInt8 called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: call.This})))
 }
 
 func (r *Runtime) dataViewProto_getInt16(call FunctionCall) Value {
 	if dv, ok := r.toObject(call.This).self.(*dataViewObject); ok {
 		return intToValue(int64(dv.viewedArrayBuf.getInt16(dv.getIdxAndByteOrder(r.toIndex(call.Argument(0)), call.Argument(1), 2))))
 	}
-	panic(r.NewTypeError("Method DataView.prototype.getInt16 called on incompatible receiver %s", call.This.String()))
+	panic(r.NewTypeError("Method DataView.prototype.getInt16 called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: call.This})))
 }
 
 func (r *Runtime) dataViewProto_getInt32(call FunctionCall) Value {
 	if dv, ok := r.toObject(call.This).self.(*dataViewObject); ok {
 		return intToValue(int64(dv.viewedArrayBuf.getInt32(dv.getIdxAndByteOrder(r.toIndex(call.Argument(0)), call.Argument(1), 4))))
 	}
-	panic(r.NewTypeError("Method DataView.prototype.getInt32 called on incompatible receiver %s", call.This.String()))
+	panic(r.NewTypeError("Method DataView.prototype.getInt32 called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: call.This})))
 }
 
 func (r *Runtime) dataViewProto_getUint8(call FunctionCall) Value {
@@ -257,21 +257,21 @@ func (r *Runtime) dataViewProto_getUint8(call FunctionCall) Value {
 		idx, _ := dv.getIdxAndByteOrder(r.toIndex(call.Argument(0)), call.Argument(1), 1)
 		return intToValue(int64(dv.viewedArrayBuf.getUint8(idx)))
 	}
-	panic(r.NewTypeError("Method DataView.prototype.getUint8 called on incompatible receiver %s", call.This.String()))
+	panic(r.NewTypeError("Method DataView.prototype.getUint8 called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: call.This})))
 }
 
 func (r *Runtime) dataViewProto_getUint16(call FunctionCall) Value {
 	if dv, ok := r.toObject(call.This).self.(*dataViewObject); ok {
 		return intToValue(int64(dv.viewedArrayBuf.getUint16(dv.getIdxAndByteOrder(r.toIndex(call.Argument(0)), call.Argument(1), 2))))
 	}
-	panic(r.NewTypeError("Method DataView.prototype.getUint16 called on incompatible receiver %s", call.This.String()))
+	panic(r.NewTypeError("Method DataView.prototype.getUint16 called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: call.This})))
 }
 
 func (r *Runtime) dataViewProto_getUint32(call FunctionCall) Value {
 	if dv, ok := r.toObject(call.This).self.(*dataViewObject); ok {
 		return intToValue(int64(dv.viewedArrayBuf.getUint32(dv.getIdxAndByteOrder(r.toIndex(call.Argument(0)), call.Argument(1), 4))))
 	}
-	panic(r.NewTypeError("Method DataView.prototype.getUint32 called on incompatible receiver %s", call.This.String()))
+	panic(r.NewTypeError("Method DataView.prototype.getUint32 called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: call.This})))
 }
 
 func (r *Runtime) dataViewProto_setFloat32(call FunctionCall) Value {
@@ -282,7 +282,7 @@ func (r *Runtime) dataViewProto_setFloat32(call FunctionCall) Value {
 		dv.viewedArrayBuf.setFloat32(idx, val, bo)
 		return _undefined
 	}
-	panic(r.NewTypeError("Method DataView.prototype.setFloat32 called on incompatible receiver %s", call.This.String()))
+	panic(r.NewTypeError("Method DataView.prototype.setFloat32 called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: call.This})))
 }
 
 func (r *Runtime) dataViewProto_setFloat64(call FunctionCall) Value {
@@ -293,7 +293,7 @@ func (r *Runtime) dataViewProto_setFloat64(call FunctionCall) Value {
 		dv.viewedArrayBuf.setFloat64(idx, val, bo)
 		return _undefined
 	}
-	panic(r.NewTypeError("Method DataView.prototype.setFloat64 called on incompatible receiver %s", call.This.String()))
+	panic(r.NewTypeError("Method DataView.prototype.setFloat64 called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: call.This})))
 }
 
 func (r *Runtime) dataViewProto_setInt8(call FunctionCall) Value {
@@ -304,7 +304,7 @@ func (r *Runtime) dataViewProto_setInt8(call FunctionCall) Value {
 		dv.viewedArrayBuf.setInt8(idx, val)
 		return _undefined
 	}
-	panic(r.NewTypeError("Method DataView.prototype.setInt8 called on incompatible receiver %s", call.This.String()))
+	panic(r.NewTypeError("Method DataView.prototype.setInt8 called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: call.This})))
 }
 
 func (r *Runtime) dataViewProto_setInt16(call FunctionCall) Value {
@@ -315,7 +315,7 @@ func (r *Runtime) dataViewProto_setInt16(call FunctionCall) Value {
 		dv.viewedArrayBuf.setInt16(idx, val, bo)
 		return _undefined
 	}
-	panic(r.NewTypeError("Method DataView.prototype.setInt16 called on incompatible receiver %s", call.This.String()))
+	panic(r.NewTypeError("Method DataView.prototype.setInt16 called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: call.This})))
 }
 
 func (r *Runtime) dataViewProto_setInt32(call FunctionCall) Value {
@@ -326,7 +326,7 @@ func (r *Runtime) dataViewProto_setInt32(call FunctionCall) Value {
 		dv.viewedArrayBuf.setInt32(idx, val, bo)
 		return _undefined
 	}
-	panic(r.NewTypeError("Method DataView.prototype.setInt32 called on incompatible receiver %s", call.This.String()))
+	panic(r.NewTypeError("Method DataView.prototype.setInt32 called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: call.This})))
 }
 
 func (r *Runtime) dataViewProto_setUint8(call FunctionCall) Value {
@@ -337,7 +337,7 @@ func (r *Runtime) dataViewProto_setUint8(call FunctionCall) Value {
 		dv.viewedArrayBuf.setUint8(idx, val)
 		return _undefined
 	}
-	panic(r.NewTypeError("Method DataView.prototype.setUint8 called on incompatible receiver %s", call.This.String()))
+	panic(r.NewTypeError("Method DataView.prototype.setUint8 called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: call.This})))
 }
 
 func (r *Runtime) dataViewProto_setUint16(call FunctionCall) Value {
@@ -348,7 +348,7 @@ func (r *Runtime) dataViewProto_setUint16(call FunctionCall) Value {
 		dv.viewedArrayBuf.setUint16(idx, val, bo)
 		return _undefined
 	}
-	panic(r.NewTypeError("Method DataView.prototype.setUint16 called on incompatible receiver %s", call.This.String()))
+	panic(r.NewTypeError("Method DataView.prototype.setUint16 called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: call.This})))
 }
 
 func (r *Runtime) dataViewProto_setUint32(call FunctionCall) Value {
@@ -359,14 +359,14 @@ func (r *Runtime) dataViewProto_setUint32(call FunctionCall) Value {
 		dv.viewedArrayBuf.setUint32(idx, val, bo)
 		return _undefined
 	}
-	panic(r.NewTypeError("Method DataView.prototype.setUint32 called on incompatible receiver %s", call.This.String()))
+	panic(r.NewTypeError("Method DataView.prototype.setUint32 called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: call.This})))
 }
 
 func (r *Runtime) typedArrayProto_getBuffer(call FunctionCall) Value {
 	if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
 		return ta.viewedArrayBuf.val
 	}
-	panic(r.NewTypeError("Method get TypedArray.prototype.buffer called on incompatible receiver %s", call.This.String()))
+	panic(r.NewTypeError("Method get TypedArray.prototype.buffer called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: call.This})))
 }
 
 func (r *Runtime) typedArrayProto_getByteLen(call FunctionCall) Value {
@@ -376,7 +376,7 @@ func (r *Runtime) typedArrayProto_getByteLen(call FunctionCall) Value {
 		}
 		return intToValue(int64(ta.length) * int64(ta.elemSize))
 	}
-	panic(r.NewTypeError("Method get TypedArray.prototype.byteLength called on incompatible receiver %s", call.This.String()))
+	panic(r.NewTypeError("Method get TypedArray.prototype.byteLength called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: call.This})))
 }
 
 func (r *Runtime) typedArrayProto_getLength(call FunctionCall) Value {
@@ -386,7 +386,7 @@ func (r *Runtime) typedArrayProto_getLength(call FunctionCall) Value {
 		}
 		return intToValue(int64(ta.length))
 	}
-	panic(r.NewTypeError("Method get TypedArray.prototype.length called on incompatible receiver %s", call.This.String()))
+	panic(r.NewTypeError("Method get TypedArray.prototype.length called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: call.This})))
 }
 
 func (r *Runtime) typedArrayProto_getByteOffset(call FunctionCall) Value {
@@ -396,7 +396,7 @@ func (r *Runtime) typedArrayProto_getByteOffset(call FunctionCall) Value {
 		}
 		return intToValue(int64(ta.offset) * int64(ta.elemSize))
 	}
-	panic(r.NewTypeError("Method get TypedArray.prototype.byteOffset called on incompatible receiver %s", call.This.String()))
+	panic(r.NewTypeError("Method get TypedArray.prototype.byteOffset called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: call.This})))
 }
 
 func (r *Runtime) typedArrayProto_copyWithin(call FunctionCall) Value {
@@ -421,7 +421,7 @@ func (r *Runtime) typedArrayProto_copyWithin(call FunctionCall) Value {
 		}
 		return call.This
 	}
-	panic(r.NewTypeError("Method TypedArray.prototype.copyWithin called on incompatible receiver %s", call.This.String()))
+	panic(r.NewTypeError("Method TypedArray.prototype.copyWithin called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: call.This})))
 }
 
 func (r *Runtime) typedArrayProto_entries(call FunctionCall) Value {
@@ -429,7 +429,7 @@ func (r *Runtime) typedArrayProto_entries(call FunctionCall) Value {
 		ta.viewedArrayBuf.ensureNotDetached(true)
 		return r.createArrayIterator(ta.val, iterationKindKeyValue)
 	}
-	panic(r.NewTypeError("Method TypedArray.prototype.entries called on incompatible receiver %s", call.This.String()))
+	panic(r.NewTypeError("Method TypedArray.prototype.entries called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: call.This})))
 }
 
 func (r *Runtime) typedArrayProto_every(call FunctionCall) Value {
@@ -454,7 +454,7 @@ func (r *Runtime) typedArrayProto_every(call FunctionCall) Value {
 		return valueTrue
 
 	}
-	panic(r.NewTypeError("Method TypedArray.prototype.every called on incompatible receiver %s", call.This.String()))
+	panic(r.NewTypeError("Method TypedArray.prototype.every called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: call.This})))
 }
 
 func (r *Runtime) typedArrayProto_fill(call FunctionCall) Value {
@@ -476,7 +476,7 @@ func (r *Runtime) typedArrayProto_fill(call FunctionCall) Value {
 		}
 		return call.This
 	}
-	panic(r.NewTypeError("Method TypedArray.prototype.fill called on incompatible receiver %s", call.This.String()))
+	panic(r.NewTypeError("Method TypedArray.prototype.fill called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: call.This})))
 }
 
 func (r *Runtime) typedArrayProto_filter(call FunctionCall) Value {
@@ -523,7 +523,7 @@ func (r *Runtime) typedArrayProto_filter(call FunctionCall) Value {
 			return ret.val
 		}
 	}
-	panic(r.NewTypeError("Method TypedArray.prototype.filter called on incompatible receiver %s", call.This.String()))
+	panic(r.NewTypeError("Method TypedArray.prototype.filter called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: call.This})))
 }
 
 func (r *Runtime) typedArrayProto_find(call FunctionCall) Value {
@@ -547,7 +547,7 @@ func (r *Runtime) typedArrayProto_find(call FunctionCall) Value {
 		}
 		return _undefined
 	}
-	panic(r.NewTypeError("Method TypedArray.prototype.find called on incompatible receiver %s", call.This.String()))
+	panic(r.NewTypeError("Method TypedArray.prototype.find called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: call.This})))
 }
 
 func (r *Runtime) typedArrayProto_findIndex(call FunctionCall) Value {
@@ -571,7 +571,7 @@ func (r *Runtime) typedArrayProto_findIndex(call FunctionCall) Value {
 		}
 		return intToValue(-1)
 	}
-	panic(r.NewTypeError("Method TypedArray.prototype.findIndex called on incompatible receiver %s", call.This.String()))
+	panic(r.NewTypeError("Method TypedArray.prototype.findIndex called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: call.This})))
 }
 
 func (r *Runtime) typedArrayProto_forEach(call FunctionCall) Value {
@@ -593,7 +593,7 @@ func (r *Runtime) typedArrayProto_forEach(call FunctionCall) Value {
 		}
 		return _undefined
 	}
-	panic(r.NewTypeError("Method TypedArray.prototype.forEach called on incompatible receiver %s", call.This.String()))
+	panic(r.NewTypeError("Method TypedArray.prototype.forEach called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: call.This})))
 }
 
 func (r *Runtime) typedArrayProto_includes(call FunctionCall) Value {
@@ -634,7 +634,7 @@ func (r *Runtime) typedArrayProto_includes(call FunctionCall) Value {
 		}
 		return valueFalse
 	}
-	panic(r.NewTypeError("Method TypedArray.prototype.includes called on incompatible receiver %s", call.This.String()))
+	panic(r.NewTypeError("Method TypedArray.prototype.includes called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: call.This})))
 }
 
 func (r *Runtime) typedArrayProto_indexOf(call FunctionCall) Value {
@@ -670,7 +670,7 @@ func (r *Runtime) typedArrayProto_indexOf(call FunctionCall) Value {
 		}
 		return intToValue(-1)
 	}
-	panic(r.NewTypeError("Method TypedArray.prototype.indexOf called on incompatible receiver %s", call.This.String()))
+	panic(r.NewTypeError("Method TypedArray.prototype.indexOf called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: call.This})))
 }
 
 func (r *Runtime) typedArrayProto_join(call FunctionCall) Value {
@@ -718,7 +718,7 @@ func (r *Runtime) typedArrayProto_keys(call FunctionCall) Value {
 		ta.viewedArrayBuf.ensureNotDetached(true)
 		return r.createArrayIterator(ta.val, iterationKindKey)
 	}
-	panic(r.NewTypeError("Method TypedArray.prototype.keys called on incompatible receiver %s", call.This.String()))
+	panic(r.NewTypeError("Method TypedArray.prototype.keys called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: call.This})))
 }
 
 func (r *Runtime) typedArrayProto_lastIndexOf(call FunctionCall) Value {
@@ -762,7 +762,7 @@ func (r *Runtime) typedArrayProto_lastIndexOf(call FunctionCall) Value {
 
 		return intToValue(-1)
 	}
-	panic(r.NewTypeError("Method TypedArray.prototype.lastIndexOf called on incompatible receiver %s", call.This.String()))
+	panic(r.NewTypeError("Method TypedArray.prototype.lastIndexOf called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: call.This})))
 }
 
 func (r *Runtime) typedArrayProto_map(call FunctionCall) Value {
@@ -785,7 +785,7 @@ func (r *Runtime) typedArrayProto_map(call FunctionCall) Value {
 		}
 		return dst.val
 	}
-	panic(r.NewTypeError("Method TypedArray.prototype.map called on incompatible receiver %s", call.This.String()))
+	panic(r.NewTypeError("Method TypedArray.prototype.map called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: call.This})))
 }
 
 func (r *Runtime) typedArrayProto_reduce(call FunctionCall) Value {
@@ -820,7 +820,7 @@ func (r *Runtime) typedArrayProto_reduce(call FunctionCall) Value {
 		}
 		return fc.Arguments[0]
 	}
-	panic(r.NewTypeError("Method TypedArray.prototype.reduce called on incompatible receiver %s", call.This.String()))
+	panic(r.NewTypeError("Method TypedArray.prototype.reduce called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: call.This})))
 }
 
 func (r *Runtime) typedArrayProto_reduceRight(call FunctionCall) Value {
@@ -855,7 +855,7 @@ func (r *Runtime) typedArrayProto_reduceRight(call FunctionCall) Value {
 		}
 		return fc.Arguments[0]
 	}
-	panic(r.NewTypeError("Method TypedArray.prototype.reduceRight called on incompatible receiver %s", call.This.String()))
+	panic(r.NewTypeError("Method TypedArray.prototype.reduceRight called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: call.This})))
 }
 
 func (r *Runtime) typedArrayProto_reverse(call FunctionCall) Value {
@@ -870,7 +870,7 @@ func (r *Runtime) typedArrayProto_reverse(call FunctionCall) Value {
 
 		return call.This
 	}
-	panic(r.NewTypeError("Method TypedArray.prototype.reverse called on incompatible receiver %s", call.This.String()))
+	panic(r.NewTypeError("Method TypedArray.prototype.reverse called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: call.This})))
 }
 
 func (r *Runtime) typedArrayProto_set(call FunctionCall) Value {
@@ -947,7 +947,7 @@ func (r *Runtime) typedArrayProto_set(call FunctionCall) Value {
 		}
 		return _undefined
 	}
-	panic(r.NewTypeError("Method TypedArray.prototype.set called on incompatible receiver %s", call.This.String()))
+	panic(r.NewTypeError("Method TypedArray.prototype.set called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: call.This})))
 }
 
 func (r *Runtime) typedArrayProto_slice(call FunctionCall) Value {
@@ -983,7 +983,7 @@ func (r *Runtime) typedArrayProto_slice(call FunctionCall) Value {
 		}
 		return dst.val
 	}
-	panic(r.NewTypeError("Method TypedArray.prototype.slice called on incompatible receiver %s", call.This.String()))
+	panic(r.NewTypeError("Method TypedArray.prototype.slice called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: call.This})))
 }
 
 func (r *Runtime) typedArrayProto_some(call FunctionCall) Value {
@@ -1007,7 +1007,7 @@ func (r *Runtime) typedArrayProto_some(call FunctionCall) Value {
 		}
 		return valueFalse
 	}
-	panic(r.NewTypeError("Method TypedArray.prototype.some called on incompatible receiver %s", call.This.String()))
+	panic(r.NewTypeError("Method TypedArray.prototype.some called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: call.This})))
 }
 
 func (r *Runtime) typedArrayProto_sort(call FunctionCall) Value {
@@ -1027,7 +1027,7 @@ func (r *Runtime) typedArrayProto_sort(call FunctionCall) Value {
 		sort.Stable(&ctx)
 		return call.This
 	}
-	panic(r.NewTypeError("Method TypedArray.prototype.sort called on incompatible receiver %s", call.This.String()))
+	panic(r.NewTypeError("Method TypedArray.prototype.sort called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: call.This})))
 }
 
 func (r *Runtime) typedArrayProto_subarray(call FunctionCall) Value {
@@ -1047,7 +1047,7 @@ func (r *Runtime) typedArrayProto_subarray(call FunctionCall) Value {
 			intToValue(newLen),
 		}).val
 	}
-	panic(r.NewTypeError("Method TypedArray.prototype.subarray called on incompatible receiver %s", call.This.String()))
+	panic(r.NewTypeError("Method TypedArray.prototype.subarray called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: call.This})))
 }
 
 func (r *Runtime) typedArrayProto_toLocaleString(call FunctionCall) Value {
@@ -1064,7 +1064,7 @@ func (r *Runtime) typedArrayProto_toLocaleString(call FunctionCall) Value {
 		}
 		return buf.String()
 	}
-	panic(r.NewTypeError("Method TypedArray.prototype.toLocaleString called on incompatible receiver %s", call.This.String()))
+	panic(r.NewTypeError("Method TypedArray.prototype.toLocaleString called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: call.This})))
 }
 
 func (r *Runtime) typedArrayProto_values(call FunctionCall) Value {
@@ -1072,7 +1072,7 @@ func (r *Runtime) typedArrayProto_values(call FunctionCall) Value {
 		ta.viewedArrayBuf.ensureNotDetached(true)
 		return r.createArrayIterator(ta.val, iterationKindValue)
 	}
-	panic(r.NewTypeError("Method TypedArray.prototype.values called on incompatible receiver %s", call.This.String()))
+	panic(r.NewTypeError("Method TypedArray.prototype.values called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: call.This})))
 }
 
 func (r *Runtime) typedArrayProto_toStringTag(call FunctionCall) Value {

+ 20 - 0
builtin_typedarrays_test.go

@@ -304,3 +304,23 @@ func TestInt32ArrayNegativeIndex(t *testing.T) {
 
 	testScript1(SCRIPT, valueTrue, t)
 }
+
+func TestTypedArrayDeleteUnconfigurable(t *testing.T) {
+	const SCRIPT = `
+	try {
+		(function() {
+			'use strict';
+			delete Uint8Array.prototype.BYTES_PER_ELEMENT;
+		})();
+	} catch(e) {
+		if (!(e instanceof TypeError)) {
+			throw e;
+		}
+		if (!e.message.startsWith("Cannot delete property")) {
+			throw e;
+		}
+	}
+	`
+
+	testScript1(SCRIPT, _undefined, t)
+}

+ 4 - 4
builtin_weakmap.go

@@ -37,7 +37,7 @@ func (r *Runtime) weakMapProto_delete(call FunctionCall) Value {
 	thisObj := r.toObject(call.This)
 	wmo, ok := thisObj.self.(*weakMapObject)
 	if !ok {
-		panic(r.NewTypeError("Method WeakMap.prototype.delete called on incompatible receiver %s", thisObj.String()))
+		panic(r.NewTypeError("Method WeakMap.prototype.delete called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: thisObj})))
 	}
 	key, ok := call.Argument(0).(*Object)
 	if ok && wmo.m.remove(key) {
@@ -50,7 +50,7 @@ func (r *Runtime) weakMapProto_get(call FunctionCall) Value {
 	thisObj := r.toObject(call.This)
 	wmo, ok := thisObj.self.(*weakMapObject)
 	if !ok {
-		panic(r.NewTypeError("Method WeakMap.prototype.get called on incompatible receiver %s", thisObj.String()))
+		panic(r.NewTypeError("Method WeakMap.prototype.get called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: thisObj})))
 	}
 	var res Value
 	if key, ok := call.Argument(0).(*Object); ok {
@@ -66,7 +66,7 @@ func (r *Runtime) weakMapProto_has(call FunctionCall) Value {
 	thisObj := r.toObject(call.This)
 	wmo, ok := thisObj.self.(*weakMapObject)
 	if !ok {
-		panic(r.NewTypeError("Method WeakMap.prototype.has called on incompatible receiver %s", thisObj.String()))
+		panic(r.NewTypeError("Method WeakMap.prototype.has called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: thisObj})))
 	}
 	key, ok := call.Argument(0).(*Object)
 	if ok && wmo.m.has(key) {
@@ -79,7 +79,7 @@ func (r *Runtime) weakMapProto_set(call FunctionCall) Value {
 	thisObj := r.toObject(call.This)
 	wmo, ok := thisObj.self.(*weakMapObject)
 	if !ok {
-		panic(r.NewTypeError("Method WeakMap.prototype.set called on incompatible receiver %s", thisObj.String()))
+		panic(r.NewTypeError("Method WeakMap.prototype.set called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: thisObj})))
 	}
 	key := r.toObject(call.Argument(0))
 	wmo.m.set(key, call.Argument(1))

+ 3 - 3
builtin_weakset.go

@@ -14,7 +14,7 @@ func (r *Runtime) weakSetProto_add(call FunctionCall) Value {
 	thisObj := r.toObject(call.This)
 	wso, ok := thisObj.self.(*weakSetObject)
 	if !ok {
-		panic(r.NewTypeError("Method WeakSet.prototype.add called on incompatible receiver %s", thisObj.String()))
+		panic(r.NewTypeError("Method WeakSet.prototype.add called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: thisObj})))
 	}
 	wso.s.set(r.toObject(call.Argument(0)), nil)
 	return call.This
@@ -24,7 +24,7 @@ func (r *Runtime) weakSetProto_delete(call FunctionCall) Value {
 	thisObj := r.toObject(call.This)
 	wso, ok := thisObj.self.(*weakSetObject)
 	if !ok {
-		panic(r.NewTypeError("Method WeakSet.prototype.delete called on incompatible receiver %s", thisObj.String()))
+		panic(r.NewTypeError("Method WeakSet.prototype.delete called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: thisObj})))
 	}
 	obj, ok := call.Argument(0).(*Object)
 	if ok && wso.s.remove(obj) {
@@ -37,7 +37,7 @@ func (r *Runtime) weakSetProto_has(call FunctionCall) Value {
 	thisObj := r.toObject(call.This)
 	wso, ok := thisObj.self.(*weakSetObject)
 	if !ok {
-		panic(r.NewTypeError("Method WeakSet.prototype.has called on incompatible receiver %s", thisObj.String()))
+		panic(r.NewTypeError("Method WeakSet.prototype.has called on incompatible receiver %s", r.objectproto_toString(FunctionCall{This: thisObj})))
 	}
 	obj, ok := call.Argument(0).(*Object)
 	if ok && wso.s.has(obj) {

+ 4 - 1
object.go

@@ -372,7 +372,10 @@ func (o *baseObject) getOwnPropStr(name unistring.String) Value {
 
 func (o *baseObject) checkDeleteProp(name unistring.String, prop *valueProperty, throw bool) bool {
 	if !prop.configurable {
-		o.val.runtime.typeErrorResult(throw, "Cannot delete property '%s' of %s", name, o.val.toString())
+		if throw {
+			r := o.val.runtime
+			panic(r.NewTypeError("Cannot delete property '%s' of %s", name, r.objectproto_toString(FunctionCall{This: o.val})))
+		}
 		return false
 	}
 	return true