Browse Source

Fixed "delete 'a'.prop". Optimised a[<const_string>] to a.<const_string>

Dmitry Panov 3 years ago
parent
commit
5b995c25f3
3 changed files with 43 additions and 5 deletions
  1. 34 3
      compiler_expr.go
  2. 7 0
      compiler_test.go
  3. 2 2
      vm.go

+ 34 - 3
compiler_expr.go

@@ -875,19 +875,50 @@ func (e *compiledSuperBracketExpr) deleteExpr() compiledExpr {
 	return e.c.superDeleteError(e.offset)
 	return e.c.superDeleteError(e.offset)
 }
 }
 
 
+func (c *compiler) checkConstantString(expr compiledExpr) (unistring.String, bool) {
+	if expr.constant() {
+		if val, ex := c.evalConst(expr); ex == nil {
+			if s, ok := val.(valueString); ok {
+				return s.string(), true
+			}
+		}
+	}
+	return "", false
+}
+
 func (c *compiler) compileBracketExpression(v *ast.BracketExpression) compiledExpr {
 func (c *compiler) compileBracketExpression(v *ast.BracketExpression) compiledExpr {
 	if sup, ok := v.Left.(*ast.SuperExpression); ok {
 	if sup, ok := v.Left.(*ast.SuperExpression); ok {
 		c.checkSuperBase(sup.Idx)
 		c.checkSuperBase(sup.Idx)
+		member := c.compileExpression(v.Member)
+		if name, ok := c.checkConstantString(member); ok {
+			r := &compiledSuperDotExpr{
+				name: name,
+			}
+			r.init(c, v.LeftBracket)
+			return r
+		}
+
 		r := &compiledSuperBracketExpr{
 		r := &compiledSuperBracketExpr{
-			member: c.compileExpression(v.Member),
+			member: member,
+		}
+		r.init(c, v.LeftBracket)
+		return r
+	}
+
+	left := c.compileExpression(v.Left)
+	member := c.compileExpression(v.Member)
+	if name, ok := c.checkConstantString(member); ok {
+		r := &compiledDotExpr{
+			left: left,
+			name: name,
 		}
 		}
 		r.init(c, v.LeftBracket)
 		r.init(c, v.LeftBracket)
 		return r
 		return r
 	}
 	}
 
 
 	r := &compiledBracketExpr{
 	r := &compiledBracketExpr{
-		left:   c.compileExpression(v.Left),
-		member: c.compileExpression(v.Member),
+		left:   left,
+		member: member,
 	}
 	}
 	r.init(c, v.LeftBracket)
 	r.init(c, v.LeftBracket)
 	return r
 	return r

+ 7 - 0
compiler_test.go

@@ -5470,6 +5470,13 @@ func TestPrivateIn(t *testing.T) {
 	testScript(SCRIPT, valueTrue, t)
 	testScript(SCRIPT, valueTrue, t)
 }
 }
 
 
+func TestDeletePropOfNonObject(t *testing.T) {
+	const SCRIPT = `
+	delete 'Test262'[100] && delete 'Test262'.a && delete 'Test262'['@'];
+	`
+	testScript(SCRIPT, valueTrue, t)
+}
+
 /*
 /*
 func TestBabel(t *testing.T) {
 func TestBabel(t *testing.T) {
 	src, err := ioutil.ReadFile("babel7.js")
 	src, err := ioutil.ReadFile("babel7.js")

+ 2 - 2
vm.go

@@ -1691,7 +1691,7 @@ func (_deleteElemStrict) exec(vm *vm) {
 type deleteProp unistring.String
 type deleteProp unistring.String
 
 
 func (d deleteProp) exec(vm *vm) {
 func (d deleteProp) exec(vm *vm) {
-	obj := vm.r.toObject(vm.stack[vm.sp-1])
+	obj := vm.stack[vm.sp-1].ToObject(vm.r)
 	if obj.self.deleteStr(unistring.String(d), false) {
 	if obj.self.deleteStr(unistring.String(d), false) {
 		vm.stack[vm.sp-1] = valueTrue
 		vm.stack[vm.sp-1] = valueTrue
 	} else {
 	} else {
@@ -1703,7 +1703,7 @@ func (d deleteProp) exec(vm *vm) {
 type deletePropStrict unistring.String
 type deletePropStrict unistring.String
 
 
 func (d deletePropStrict) exec(vm *vm) {
 func (d deletePropStrict) exec(vm *vm) {
-	obj := vm.r.toObject(vm.stack[vm.sp-1])
+	obj := vm.stack[vm.sp-1].ToObject(vm.r)
 	obj.self.deleteStr(unistring.String(d), true)
 	obj.self.deleteStr(unistring.String(d), true)
 	vm.stack[vm.sp-1] = valueTrue
 	vm.stack[vm.sp-1] = valueTrue
 	vm.pc++
 	vm.pc++