소스 검색

Initialise Function.prototype also when it's being set or deleted. Fixes #131.

Dmitry Panov 5 년 전
부모
커밋
3d32615791
2개의 변경된 파일47개의 추가작업 그리고 3개의 파일을 삭제
  1. 27 3
      func.go
  2. 20 0
      runtime_test.go

+ 27 - 3
func.go

@@ -35,17 +35,41 @@ func (f *nativeFuncObject) exportType() reflect.Type {
 	return reflect.TypeOf(f.f)
 	return reflect.TypeOf(f.f)
 }
 }
 
 
-func (f *funcObject) getPropStr(name string) Value {
-	switch name {
-	case "prototype":
+func (f *funcObject) _addProto(n string) Value {
+	if n == "prototype" {
 		if _, exists := f.values["prototype"]; !exists {
 		if _, exists := f.values["prototype"]; !exists {
 			return f.addPrototype()
 			return f.addPrototype()
 		}
 		}
 	}
 	}
+	return nil
+}
+
+func (f *funcObject) getPropStr(name string) Value {
+	if v := f._addProto(name); v != nil {
+		return v
+	}
 
 
 	return f.baseObject.getPropStr(name)
 	return f.baseObject.getPropStr(name)
 }
 }
 
 
+func (f *funcObject) putStr(name string, val Value, throw bool) {
+	f._addProto(name)
+	f.baseObject.putStr(name, val, throw)
+}
+
+func (f *funcObject) put(n Value, val Value, throw bool) {
+	f.putStr(n.String(), val, throw)
+}
+
+func (f *funcObject) deleteStr(name string, throw bool) bool {
+	f._addProto(name)
+	return f.baseObject.deleteStr(name, throw)
+}
+
+func (f *funcObject) delete(n Value, throw bool) bool {
+	return f.deleteStr(n.String(), throw)
+}
+
 func (f *funcObject) addPrototype() Value {
 func (f *funcObject) addPrototype() Value {
 	proto := f.val.runtime.NewObject()
 	proto := f.val.runtime.NewObject()
 	proto.self._putProp("constructor", f.val, true, false, true)
 	proto.self._putProp("constructor", f.val, true, false, true)

+ 20 - 0
runtime_test.go

@@ -1327,6 +1327,26 @@ func TestProtoGetter(t *testing.T) {
 	testScript1(SCRIPT, valueTrue, t)
 	testScript1(SCRIPT, valueTrue, t)
 }
 }
 
 
+func TestFuncProto(t *testing.T) {
+	const SCRIPT = `
+	"use strict";
+	function A() {}
+	A.__proto__ = Object;
+	A.prototype = {};
+
+	function B() {}
+	B.__proto__ = Object.create(null);
+	var thrown = false;
+	try {
+		delete B.prototype;
+	} catch (e) {
+		thrown = e instanceof TypeError;
+	}
+	thrown;
+	`
+	testScript1(SCRIPT, valueTrue, t)
+}
+
 /*
 /*
 func TestArrayConcatSparse(t *testing.T) {
 func TestArrayConcatSparse(t *testing.T) {
 function foo(a,b,c)
 function foo(a,b,c)