diff --git a/src/interpreter/ByteCodeInterpreter.cpp b/src/interpreter/ByteCodeInterpreter.cpp index 930f432a0..e2e14ba6e 100644 --- a/src/interpreter/ByteCodeInterpreter.cpp +++ b/src/interpreter/ByteCodeInterpreter.cpp @@ -2413,7 +2413,7 @@ NEVER_INLINE void ByteCodeInterpreter::classOperation(ExecutionState& state, Cre } } - Object* proto = new Object(state); + ScriptClassConstructorPrototypeObject* proto = new ScriptClassConstructorPrototypeObject(state); proto->setPrototype(state, protoParent); ScriptClassConstructorFunctionObject* constructor; @@ -3045,7 +3045,7 @@ NEVER_INLINE void ByteCodeInterpreter::objectDefineOwnPropertyOperation(Executio ObjectPropertyName objPropName = ObjectPropertyName(state, propertyStringOrSymbol); // http://www.ecma-international.org/ecma-262/6.0/#sec-__proto__-property-names-in-object-initializers - if (propertyStringOrSymbol.isString() && propertyStringOrSymbol.asString()->equals("__proto__")) { + if (!willBeObject.asObject()->isScriptClassConstructorPrototypeObject() && (propertyStringOrSymbol.isString() && propertyStringOrSymbol.asString()->equals("__proto__"))) { willBeObject.asObject()->setPrototype(state, value); } else { willBeObject.asObject()->defineOwnProperty(state, objPropName, ObjectPropertyDescriptor(value, code->m_presentAttribute)); @@ -3056,7 +3056,7 @@ NEVER_INLINE void ByteCodeInterpreter::objectDefineOwnPropertyWithNameOperation( { const Value& willBeObject = registerFile[code->m_objectRegisterIndex]; // http://www.ecma-international.org/ecma-262/6.0/#sec-__proto__-property-names-in-object-initializers - if (code->m_propertyName == state.context()->staticStrings().__proto__) { + if (!willBeObject.asObject()->isScriptClassConstructorPrototypeObject() && (code->m_propertyName == state.context()->staticStrings().__proto__)) { willBeObject.asObject()->setPrototype(state, registerFile[code->m_loadRegisterIndex]); } else { willBeObject.asObject()->defineOwnProperty(state, ObjectPropertyName(code->m_propertyName), ObjectPropertyDescriptor(registerFile[code->m_loadRegisterIndex], code->m_presentAttribute)); @@ -3183,7 +3183,7 @@ NEVER_INLINE void ByteCodeInterpreter::defineObjectGetterSetter(ExecutionState& if (code->m_isGetter) { fnName = createObjectPropertyFunctionName(state, pName, "get "); } else { - Value fnName = createObjectPropertyFunctionName(state, pName, "set "); + fnName = createObjectPropertyFunctionName(state, pName, "set "); } fn->defineOwnProperty(state, state.context()->staticStrings().name, ObjectPropertyDescriptor(fnName)); JSGetterSetter* gs; diff --git a/src/parser/ast/ClassBodyNode.h b/src/parser/ast/ClassBodyNode.h index d05ee2ab5..ce93a9046 100644 --- a/src/parser/ast/ClassBodyNode.h +++ b/src/parser/ast/ClassBodyNode.h @@ -99,7 +99,7 @@ class ClassBodyNode : public Node, public DestructibleNode { if (hasKey) { codeBlock->pushCode(ObjectDefineOwnPropertyWithNameOperation(ByteCodeLOC(m_loc.index), destIndex, propertyAtomicName, valueIndex, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent)), context, this); } else { - codeBlock->pushCode(ObjectDefineOwnPropertyOperation(ByteCodeLOC(m_loc.index), destIndex, propertyIndex, valueIndex, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent), false), context, this); + codeBlock->pushCode(ObjectDefineOwnPropertyOperation(ByteCodeLOC(m_loc.index), destIndex, propertyIndex, valueIndex, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent), true), context, this); context->giveUpRegister(); // for drop property index } } else if (p->kind() == ClassElementNode::Kind::Get) { diff --git a/src/parser/esprima_cpp/esprima.cpp b/src/parser/esprima_cpp/esprima.cpp index ba54c519b..fb9d8869e 100644 --- a/src/parser/esprima_cpp/esprima.cpp +++ b/src/parser/esprima_cpp/esprima.cpp @@ -3924,9 +3924,6 @@ class Parser { case YieldKeyword: { // TODO consider case that class method is generator function if (builder.isNodeGenerator()) { - if (this->context->strict) { - this->throwError("Cannot use yield as a label in strict mode"); - } statement = this->parseLabelledStatement(builder); } else { statement = this->parseExpressionStatement(builder); diff --git a/src/runtime/PointerValue.h b/src/runtime/PointerValue.h index 3dcdd5daa..cd2d023ee 100644 --- a/src/runtime/PointerValue.h +++ b/src/runtime/PointerValue.h @@ -104,6 +104,11 @@ class PointerValue : public gc { return false; } + virtual bool isScriptClassConstructorPrototypeObject() const + { + return false; + } + virtual bool isArrayObject() const { return false; diff --git a/src/runtime/ScriptClassConstructorFunctionObject.h b/src/runtime/ScriptClassConstructorFunctionObject.h index 8cc298dcd..0c8f4cb38 100644 --- a/src/runtime/ScriptClassConstructorFunctionObject.h +++ b/src/runtime/ScriptClassConstructorFunctionObject.h @@ -24,6 +24,19 @@ namespace Escargot { +class ScriptClassConstructorPrototypeObject : public Object { +public: + explicit ScriptClassConstructorPrototypeObject(ExecutionState& state) + : Object(state) + { + } + + virtual bool isScriptClassConstructorPrototypeObject() const override + { + return true; + } +}; + class ScriptClassConstructorFunctionObject : public ScriptFunctionObject { public: ScriptClassConstructorFunctionObject(ExecutionState& state, CodeBlock* codeBlock, LexicalEnvironment* outerEnvironment, Object* homeObject, String* classSourceCode); diff --git a/tools/test/spidermonkey/excludelist.txt b/tools/test/spidermonkey/excludelist.txt index 1a322b542..fc333ee82 100644 --- a/tools/test/spidermonkey/excludelist.txt +++ b/tools/test/spidermonkey/excludelist.txt @@ -45,23 +45,20 @@ non262/TypedObject/structtypeindexedfields.js non262/TypedObject/structtypeprototype.js non262/TypedObject/structtypereflection.js non262/TypedObject/structtypestructuralassign.js +non262/BigInt/decimal.js +non262/BigInt/large-bit-length.js +non262/BigInt/mod.js +non262/BigInt/Number-conversion-rounding.js # These tests include features of ES7 non262/Array/slice-sparse-with-large-index.js non262/Array/unscopables.js non262/Array/unshift-01.js +non262/arrow-functions/arrow-not-as-end-of-statement.js # TODO -non262/arrow-functions/arrow-not-as-end-of-statement.js non262/arrow-functions/yield-in-arrow.js -non262/BigInt/decimal.js -non262/BigInt/large-bit-length.js -non262/BigInt/mod.js -non262/BigInt/Number-conversion-rounding.js non262/class/className.js -non262/class/methDefnGen.js -non262/class/methodInstallation.js -non262/class/methodName.js non262/class/newTargetArrow.js non262/class/newTargetDefaults.js non262/class/newTargetDVG.js