Backed out 7 changesets (bug 1377007) for web platform reftests failures on CSS2/borders. r=backout

Backed out changeset c30bc5d5adbc (bug 1377007)
Backed out changeset 33fdf9e531e2 (bug 1377007)
Backed out changeset 267abdb38036 (bug 1377007)
Backed out changeset 4a452c3ac115 (bug 1377007)
Backed out changeset e9310960c9e6 (bug 1377007)
Backed out changeset 8e5e61dfbbaf (bug 1377007)
Backed out changeset 9ac83e79e656 (bug 1377007)
This commit is contained in:
Narcis Beleuzu 2017-12-15 02:16:50 +02:00
parent 8274652feb
commit 996e222d3a
360 changed files with 101 additions and 15355 deletions

View File

@ -307,7 +307,6 @@ js/xpconnect/**
js/src/devtools/**
js/src/octane/**
js/src/jit-test/**
js/src/jsapi-tests/binast/**
js/src/tests/**
js/src/Y.js

View File

@ -408,18 +408,3 @@ def enable_pipeline_operator(value):
set_config('ENABLE_PIPELINE_OPERATOR', enable_pipeline_operator)
set_define('ENABLE_PIPELINE_OPERATOR', enable_pipeline_operator)
# Experimental support for BinAST
# ==============================================================
@depends(target, milestone)
def enable_build_binast(target, milestone):
# For reasons unknown at this time, BinAST causes timeouts on win32
# and failures on Android.
if milestone.is_nightly and not (target.kernel == 'WINNT' and target.cpu == 'x86') and not (target.os == 'Android'):
return True
set_define('JS_BUILD_BINAST', enable_build_binast)
set_config('JS_BUILD_BINAST', enable_build_binast)

View File

@ -867,9 +867,6 @@ class JS_PUBLIC_API(AutoGCRooter)
enum {
VALARRAY = -2, /* js::AutoValueArray */
PARSER = -3, /* js::frontend::Parser */
#if defined(JS_BUILD_BINAST)
BINPARSER = -4, /* js::frontend::BinSource */
#endif // defined(JS_BUILD_BINAST)
VALVECTOR = -10, /* js::AutoValueVector */
IDVECTOR = -11, /* js::AutoIdVector */
OBJVECTOR = -14, /* js::AutoObjectVector */

View File

@ -32,7 +32,6 @@ def directories(pathmodule, cwd, fixup=lambda s: s):
DIR = directories(os.path, os.getcwd())
PDIR = directories(posixpath, os.environ["PWD"],
fixup=lambda s: re.sub(r'^(\w):', r'/\1', s))
env['CPP_UNIT_TESTS_DIR_JS_SRC'] = DIR.js_src
parser = argparse.ArgumentParser(
description='Run a spidermonkey shell build job')

File diff suppressed because it is too large Load Diff

View File

@ -1,278 +0,0 @@
#ifndef frontend_BinSource_h
#define frontend_BinSource_h
/**
* A Binary AST parser.
*
* At the time of this writing, this parser implements the grammar of ES5
* and trusts its input (in particular, variable declarations).
*/
#include "mozilla/Maybe.h"
#include "frontend/BinTokenReaderTester.h"
#include "frontend/FullParseHandler.h"
#include "frontend/ParseContext.h"
#include "frontend/ParseNode.h"
#include "frontend/SharedContext.h"
#include "js/GCHashTable.h"
#include "js/GCVector.h"
#include "js/Result.h"
namespace js {
namespace frontend {
class BinASTParser;
/**
* The parser for a Binary AST.
*
* By design, this parser never needs to backtrack or look ahead. Errors are not
* recoverable.
*/
class BinASTParser : private JS::AutoGCRooter, public ErrorReporter
{
using Names = JS::GCVector<JSString*, 8>;
using Tokenizer = BinTokenReaderTester;
using Chars = Tokenizer::Chars;
public:
BinASTParser(JSContext* cx, LifoAlloc& alloc, UsedNameTracker& usedNames, const JS::ReadOnlyCompileOptions& options)
: AutoGCRooter(cx, BINPARSER)
, traceListHead_(nullptr)
, options_(options)
, cx_(cx)
, alloc_(alloc)
, nodeAlloc_(cx, alloc)
, keepAtoms_(cx)
, parseContext_(nullptr)
, usedNames_(usedNames)
, factory_(cx, alloc, nullptr, SourceKind::Binary)
{
cx_->frontendCollectionPool().addActiveCompilation();
tempPoolMark_ = alloc.mark();
}
~BinASTParser()
{
alloc_.release(tempPoolMark_);
/*
* The parser can allocate enormous amounts of memory for large functions.
* Eagerly free the memory now (which otherwise won't be freed until the
* next GC) to avoid unnecessary OOMs.
*/
alloc_.freeAllIfHugeAndUnused();
cx_->frontendCollectionPool().removeActiveCompilation();
}
/**
* Parse a buffer, returning a node (which may be nullptr) in case of success
* or Nothing() in case of error.
*
* The instance of `ParseNode` MAY NOT survive the `BinASTParser`. Indeed,
* destruction of the `BinASTParser` will also destroy the `ParseNode`.
*
* In case of error, the parser reports the JS error.
*/
JS::Result<ParseNode*> parse(const uint8_t* start, const size_t length);
JS::Result<ParseNode*> parse(const Vector<uint8_t>& data);
private:
MOZ_MUST_USE JS::Result<ParseNode*> parseAux(const uint8_t* start, const size_t length);
// --- Raise errors.
//
// These methods return a (failed) JS::Result for convenience.
MOZ_MUST_USE mozilla::GenericErrorResult<JS::Error&> raiseInvalidKind(const char* superKind, const BinKind kind);
MOZ_MUST_USE mozilla::GenericErrorResult<JS::Error&> raiseInvalidField(const char* kind, const BinField field);
MOZ_MUST_USE mozilla::GenericErrorResult<JS::Error&> raiseInvalidEnum(const char* kind, const Chars& value);
MOZ_MUST_USE mozilla::GenericErrorResult<JS::Error&> raiseMissingField(const char* kind, const BinField field);
MOZ_MUST_USE mozilla::GenericErrorResult<JS::Error&> raiseEmpty(const char* description);
MOZ_MUST_USE mozilla::GenericErrorResult<JS::Error&> raiseOOM();
MOZ_MUST_USE mozilla::GenericErrorResult<JS::Error&> raiseError(const char* description);
MOZ_MUST_USE mozilla::GenericErrorResult<JS::Error&> raiseError(BinKind kind, const char* description);
// Ensure that this parser will never be used again.
void poison();
// --- Parse full nodes (methods are sorted by alphabetical order)
//
// These method may NEVER return `nullptr`. // FIXME: We can probably optimize Result<> based on this.
MOZ_MUST_USE JS::Result<ParseNode*> parseBlockStatement();
MOZ_MUST_USE JS::Result<ParseNode*> parseCatchClause();
MOZ_MUST_USE JS::Result<ParseNode*> parseExpression();
MOZ_MUST_USE JS::Result<ParseNode*> parseForInit();
MOZ_MUST_USE JS::Result<ParseNode*> parseForInInit();
MOZ_MUST_USE JS::Result<ParseNode*> parseIdentifier();
MOZ_MUST_USE JS::Result<ParseNode*> parseObjectPropertyName();
MOZ_MUST_USE JS::Result<ParseNode*> parseObjectMember();
MOZ_MUST_USE JS::Result<ParseNode*> parsePattern(); // Parse a *binding* pattern.
MOZ_MUST_USE JS::Result<ParseNode*> parsePropertyName();
MOZ_MUST_USE JS::Result<ParseNode*> parseProgram();
MOZ_MUST_USE JS::Result<ParseNode*> parseStatement();
MOZ_MUST_USE JS::Result<ParseNode*> parseSwitchCase();
MOZ_MUST_USE JS::Result<ParseNode*> parseVariableDeclarator();
// --- Parse lists of nodes (methods are sorted by alphabetical order)
MOZ_MUST_USE JS::Result<ParseNode*> parseArgumentList();
MOZ_MUST_USE JS::Result<ParseNode*> parseDirectiveList();
MOZ_MUST_USE JS::Result<ParseNode*> parseExpressionList(bool acceptElisions);
// Returns a list of PNK_COLON.
MOZ_MUST_USE JS::Result<ParseNode*> parseObjectMemberList();
MOZ_MUST_USE JS::Result<ParseNode*> parseStatementList();
MOZ_MUST_USE JS::Result<ParseNode*> parseSwitchCaseList();
// --- Parse the contents of a node whose kind has already been determined.
MOZ_MUST_USE JS::Result<ParseNode*> parseArrayExpressionAux(const BinKind kind, const Tokenizer::BinFields& fields);
MOZ_MUST_USE JS::Result<ParseNode*> parseBreakOrContinueStatementAux(const BinKind kind, const Tokenizer::BinFields& fields);
MOZ_MUST_USE JS::Result<ParseNode*> parseBlockStatementAux(const BinKind kind, const Tokenizer::BinFields& fields);
MOZ_MUST_USE JS::Result<ParseNode*> parseExpressionStatementAux(const BinKind kind, const Tokenizer::BinFields& fields);
MOZ_MUST_USE JS::Result<ParseNode*> parseExpressionAux(const BinKind kind, const Tokenizer::BinFields& fields);
MOZ_MUST_USE JS::Result<ParseNode*> parseFunctionAux(const BinKind kind, const Tokenizer::BinFields& fields);
MOZ_MUST_USE JS::Result<ParseNode*> parseIdentifierAux(const BinKind, const Tokenizer::BinFields& fields, const bool expectObjectPropertyName = false);
MOZ_MUST_USE JS::Result<ParseNode*> parseMemberExpressionAux(const BinKind kind, const Tokenizer::BinFields& fields);
MOZ_MUST_USE JS::Result<ParseNode*> parseNumericLiteralAux(const BinKind kind, const Tokenizer::BinFields& fields);
MOZ_MUST_USE JS::Result<ParseNode*> parseObjectExpressionAux(const BinKind kind, const Tokenizer::BinFields& fields);
MOZ_MUST_USE JS::Result<ParseNode*> parsePatternAux(const BinKind kind, const Tokenizer::BinFields& fields);
MOZ_MUST_USE JS::Result<ParseNode*> parseStringLiteralAux(const BinKind kind, const Tokenizer::BinFields& fields);
MOZ_MUST_USE JS::Result<ParseNode*> parseStatementAux(const BinKind kind, const Tokenizer::BinFields& fields);
MOZ_MUST_USE JS::Result<ParseNode*> parseVariableDeclarationAux(const BinKind kind, const Tokenizer::BinFields& fields);
// --- Auxiliary parsing functions that may have a side-effect on the parser but do not return a node.
MOZ_MUST_USE JS::Result<Ok> checkEmptyTuple(const BinKind kind, const Tokenizer::BinFields& fields);
MOZ_MUST_USE JS::Result<Ok> parseElisionAux(const BinKind kind, const Tokenizer::BinFields& fields);
// Parse full scope information to the current innermost scope.
MOZ_MUST_USE JS::Result<Ok> parseAndUpdateCurrentScope();
// Parse full scope information to a specific var scope / let scope combination.
MOZ_MUST_USE JS::Result<Ok> parseAndUpdateScope(ParseContext::Scope& varScope, ParseContext::Scope& letScope);
// Parse a list of names and add it to a given scope.
MOZ_MUST_USE JS::Result<Ok> parseAndUpdateScopeNames(ParseContext::Scope& scope, DeclarationKind kind);
MOZ_MUST_USE JS::Result<Ok> parseStringList(MutableHandle<Maybe<Names>> out);
// --- Utilities.
MOZ_MUST_USE JS::Result<ParseNode*> appendDirectivesToBody(ParseNode* body, ParseNode* directives);
// Read a string as a `Chars`.
MOZ_MUST_USE JS::Result<Ok> readString(Maybe<Chars>& out);
MOZ_MUST_USE JS::Result<Ok> readString(MutableHandleAtom out);
MOZ_MUST_USE JS::Result<bool> readBool();
MOZ_MUST_USE JS::Result<double> readNumber();
const ReadOnlyCompileOptions& options() const override {
return this->options_;
}
// Names
bool hasUsedName(HandlePropertyName name);
// --- GC.
void trace(JSTracer* trc) {
ObjectBox::TraceList(trc, traceListHead_);
}
public:
ObjectBox* newObjectBox(JSObject* obj) {
MOZ_ASSERT(obj);
/*
* We use JSContext.tempLifoAlloc to allocate parsed objects and place them
* on a list in this Parser to ensure GC safety. Thus the tempLifoAlloc
* arenas containing the entries must be alive until we are done with
* scanning, parsing and code generation for the whole script or top-level
* function.
*/
ObjectBox* objbox = alloc_.new_<ObjectBox>(obj, traceListHead_);
if (!objbox) {
ReportOutOfMemory(cx_);
return nullptr;
}
traceListHead_ = objbox;
return objbox;
}
ParseNode* allocParseNode(size_t size) {
MOZ_ASSERT(size == sizeof(ParseNode));
return static_cast<ParseNode*>(nodeAlloc_.allocNode());
}
JS_DECLARE_NEW_METHODS(new_, allocParseNode, inline)
private: // Implement ErrorReporter
virtual void lineAndColumnAt(size_t offset, uint32_t* line, uint32_t* column) const override {
*line = 0;
*column = offset;
}
virtual void currentLineAndColumn(uint32_t* line, uint32_t* column) const override {
*line = 0;
*column = offset();
}
size_t offset() const {
if (tokenizer_.isSome())
return tokenizer_->offset();
return 0;
}
virtual bool hasTokenizationStarted() const override {
return tokenizer_.isSome();
}
virtual void reportErrorNoOffsetVA(unsigned errorNumber, va_list args) override;
virtual const char* getFilename() const override {
return this->options_.filename();
}
ObjectBox* traceListHead_;
const ReadOnlyCompileOptions& options_;
JSContext* cx_;
LifoAlloc& alloc_;
LifoAlloc::Mark tempPoolMark_;
ParseNodeAllocator nodeAlloc_;
// Root atoms and objects allocated for the parse tree.
AutoKeepAtoms keepAtoms_;
// The current ParseContext, holding directives, etc.
ParseContext* parseContext_;
UsedNameTracker& usedNames_;
Maybe<Tokenizer> tokenizer_;
FullParseHandler factory_;
friend class BinParseContext;
// Needs access to AutoGCRooter.
friend void TraceBinParser(JSTracer* trc, AutoGCRooter* parser);
};
class BinParseContext : public ParseContext
{
public:
BinParseContext(JSContext* cx, BinASTParser* parser, SharedContext* sc, Directives* newDirectives)
: ParseContext(cx, parser->parseContext_, sc, *parser,
parser->usedNames_, newDirectives, /* isFull = */ true)
{ }
};
} // namespace frontend
} // namespace js
#endif // frontend_BinSource_h

View File

@ -1,29 +0,0 @@
#include "frontend/BinToken.h"
#include <sys/types.h>
namespace js {
namespace frontend {
const char* BINKIND_DESCRIPTIONS[] = {
#define WITH_KIND(_, SPEC_NAME) #SPEC_NAME,
FOR_EACH_BIN_KIND(WITH_KIND)
#undef WITH_KIND
};
const char* BINFIELD_DESCRIPTIONS[] = {
#define WITH_FIELD(_, SPEC_NAME) #SPEC_NAME,
FOR_EACH_BIN_FIELD(WITH_FIELD)
#undef WITH_FIELD
};
const char* describeBinKind(const BinKind& kind) {
return BINKIND_DESCRIPTIONS[static_cast<size_t>(kind)];
}
const char* describeBinField(const BinField& field) {
return BINFIELD_DESCRIPTIONS[static_cast<size_t>(field)];
}
} // namespace frontend
} // namespace js

View File

@ -1,201 +0,0 @@
#ifndef frontend_BinToken_h
#define frontend_BinToken_h
/**
* Definition of Binary AST tokens.
*
* In the Binary AST world, an AST is composed of nodes, where a node is
* defined by:
* - a Kind (see `BinKind`);
* - a list of fields, where each field is:
* - a Name (see `BinField`);
* - a Value, which may be either a node or a primitive value.
*
* The mapping between Kind and list of fields is determined entirely by
* the grammar of Binary AST. The mapping between (Kind, Name) and the structure
* of Value is also determined entirely by the grammar of Binary AST.
*
* As per the specifications of Binary AST, kinds may be added as the language
* grows, but never removed. The mapping between Kind and list of fields may
* also change to add new fields or make some fields optional, but may never
* remove a field. Finally, the mapping between (Kind, Name) and the structure
* of Value may be modified to add new possible values, but never to remove a
* value.
*
* A Binary AST parser must be able to fail gracefully when confronted with
* unknown Kinds or Names.
*
* At the time of this writing, the Binary AST defined from the Babylon AST
* (see https://github.com/babel/babylon/blob/master/ast/spec.md) restricted
* to ES5, with a few amendments to store additional scoping data and to
* represent the empty AST.
*
* Future versions of the Binary AST will progressively grow to encompass ES6
* and beyond.
*/
namespace js {
namespace frontend {
/**
* The different kinds of Binary AST nodes, as per the specifications of
* Binary AST.
*
* These kinds match roughly with the `ParseNodeKind` used internally.
*
* Usage:
*
* ```c++
* #define WITH_KIND(CPP_NAME, SPEC_NAME) ...
* FOR_EACH_BIN_KIND(WITH_KIND)
* ```
*
*
* (sorted by alphabetical order)
*/
#define FOR_EACH_BIN_KIND(F) \
F(ArrayExpression, ArrayExpression) \
F(AssignmentExpression, AssignmentExpression) \
F(AssignmentOperator, AssignmentOperator) \
F(BinaryExpression, BinaryExpression) \
F(BinaryOperator, BinaryOperator) \
F(BINJS_Scope, BINJS:Scope) \
F(BlockStatement, BlockStatement) \
F(BooleanLiteral, BooleanLiteral) \
F(BracketExpression, BracketExpression) \
F(BreakStatement, BreakStatement) \
F(CallExpression, CallExpression) \
F(CatchClause, CatchClause) \
F(ComputedPropertyName, ComputedPropertyName) \
F(ConditionalExpression, ConditionalExpression) \
F(ContinueStatement, ContinueStatement) \
F(DebuggerStatement, DebuggerStatement) \
F(Declaration, Declaration) \
F(Directive, Directive) \
F(DirectiveLiteral, DirectiveLiteral) \
F(DotExpression, DotExpression) \
F(DoWhileStatement, DoWhileStatement) \
F(Elision, Elision) \
F(EmptyStatement, EmptyStatement) \
F(Expression, Expression) \
F(ExpressionStatement, ExpressionStatement) \
F(ForStatement, ForStatement) \
F(ForInStatement, ForInStatement) \
F(FunctionExpression, FunctionExpression) \
F(FunctionDeclaration, FunctionDeclaration) \
F(Identifier, Identifier) \
F(IfStatement, IfStatement) \
F(LabeledStatement, LabeledStatement) \
F(Literal, Literal) \
F(LogicalExpression, LogicalExpression) \
F(LogicalOperator, LogicalOperator) \
F(NewExpression, NewExpression) \
F(NullLiteral, NullLiteral) \
F(NumericLiteral, NumericLiteral) \
F(ObjectExpression, ObjectExpression) \
F(ObjectGetter, ObjectGetter) \
F(ObjectMethod, ObjectMethod) \
F(ObjectSetter, ObjectSetter) \
F(ObjectProperty, ObjectProperty) \
F(Pattern, Pattern) \
F(Program, Program) \
F(PropertyKind, PropertyKind) \
F(RegExpLiteral, RegExpLiteral) \
F(ReturnStatement, ReturnStatement) \
F(SequenceExpression, SequenceExpression) \
F(StringLiteral, StringLiteral) \
F(Statement, Statement) \
F(SwitchCase, SwitchCase) \
F(SwitchStatement, SwitchStatement) \
F(ThisExpression, ThisExpression) \
F(ThrowStatement, ThrowStatement) \
F(TryStatement, TryStatement) \
F(UnaryExpression, UnaryExpression) \
F(UnaryOperator, UnaryOperator) \
F(UpdateExpression, UpdateExpression) \
F(UpdateOperator, UpdateOperator) \
F(VariableDeclaration, VariableDeclaration) \
F(VariableDeclarator, VariableDeclarator) \
F(VariableKind, VariableKind) \
F(WhileStatement, WhileStatement) \
F(WithStatement, WithStatement)
enum class BinKind {
#define EMIT_ENUM(name, _) name,
FOR_EACH_BIN_KIND(EMIT_ENUM)
#undef EMIT_ENUM
BINKIND_LIMIT /* domain size */
};
const char* describeBinKind(const BinKind& kind);
/**
* The different fields of Binary AST nodes, as per the specifications of
* Binary AST.
*
* Usage:
*
* ```c++
* #define WITH_FIELD(CPP_NAME, SPEC_NAME) ...
* FOR_EACH_BIN_FIELD(WITH_FIELD)
* ```
*
* (sorted by alphabetical order)
*/
#define FOR_EACH_BIN_FIELD(F) \
F(Alternate, alternate) \
F(Argument, argument) \
F(Arguments, arguments) \
F(BINJS_CapturedNames, BINJS:CapturedNames) \
F(BINJS_ConstDeclaredNames, BINJS:ConstDeclaredNames) \
F(BINJS_HasDirectEval, BINJS:HasDirectEval) \
F(BINJS_LetDeclaredNames, BINJS:LetDeclaredNames) \
F(BINJS_VarDeclaredNames, BINJS:VarDeclaredNames) \
F(BINJS_Scope, BINJS:Scope) \
F(Block, block) \
F(Callee, callee) \
F(Cases, cases) \
F(Consequent, consequent) \
F(Body, body) \
F(Declarations, declarations) \
F(Directives, directives) \
F(Discriminant, discriminant) \
F(Elements, elements) \
F(Expression, expression) \
F(Expressions, expressions) \
F(Finalizer, finalizer) \
F(Flags, flags) \
F(Handler, handler) \
F(Id, id) \
F(Init, init) \
F(Key, key) \
F(Kind, kind) \
F(Label, label) \
F(Left, left) \
F(Name, name) \
F(Object, object) \
F(Operator, operator) \
F(Param, param) \
F(Params, params) \
F(Pattern, pattern) \
F(Prefix, prefix) \
F(Properties, properties) \
F(Property, property) \
F(Right, right) \
F(Test, test) \
F(Update, update) \
F(Value, value)
enum class BinField {
#define EMIT_ENUM(name, _) name,
FOR_EACH_BIN_FIELD(EMIT_ENUM)
#undef EMIT_ENUM
BINFIELD_LIMIT /* domain size */
};
const char* describeBinField(const BinField& kind);
} // namespace frontend
} // namespace js
#endif // frontend_BinToken_h

View File

@ -1,536 +0,0 @@
#include "frontend/BinTokenReaderTester.h"
#include "mozilla/EndianUtils.h"
#include "gc/Zone.h"
namespace js {
namespace frontend {
using BinFields = BinTokenReaderTester::BinFields;
using AutoList = BinTokenReaderTester::AutoList;
using AutoTaggedTuple = BinTokenReaderTester::AutoTaggedTuple;
using AutoTuple = BinTokenReaderTester::AutoTuple;
BinTokenReaderTester::BinTokenReaderTester(JSContext* cx, const uint8_t* start, const size_t length)
: cx_(cx)
, start_(start)
, current_(start)
, stop_(start + length)
, latestKnownGoodPos_(0)
{ }
BinTokenReaderTester::BinTokenReaderTester(JSContext* cx, const Vector<uint8_t>& chars)
: cx_(cx)
, start_(chars.begin())
, current_(chars.begin())
, stop_(chars.end())
, latestKnownGoodPos_(0)
{ }
bool
BinTokenReaderTester::raiseError(const char* description)
{
MOZ_ASSERT(!cx_->isExceptionPending());
TokenPos pos = this->pos();
JS_ReportErrorASCII(cx_, "BinAST parsing error: %s at offsets %u => %u",
description, pos.begin, pos.end);
return false;
}
bool
BinTokenReaderTester::readBuf(uint8_t* bytes, uint32_t len)
{
MOZ_ASSERT(!cx_->isExceptionPending());
MOZ_ASSERT(len > 0);
if (stop_ < current_ + len)
return raiseError("Buffer exceeds length");
for (uint32_t i = 0; i < len; ++i)
*bytes++ = *current_++;
return true;
}
bool
BinTokenReaderTester::readByte(uint8_t* byte)
{
return readBuf(byte, 1);
}
// Nullable booleans:
//
// 0 => false
// 1 => true
// 2 => null
bool
BinTokenReaderTester::readMaybeBool(Maybe<bool>& result)
{
updateLatestKnownGood();
uint8_t byte;
if (!readByte(&byte))
return false;
switch (byte) {
case 0:
result = Some(false);
break;
case 1:
result = Some(true);
break;
case 2:
result = Nothing();
break;
default:
return raiseError("Invalid boolean value");
}
return true;
}
bool
BinTokenReaderTester::readBool(bool& out)
{
Maybe<bool> result;
if (!readMaybeBool(result))
return false;
if (result.isNothing())
return raiseError("Empty boolean value");
out = *result;
return true;
}
// Nullable doubles (little-endian)
//
// 0x7FF0000000000001 (signaling NaN) => null
// anything other 64 bit sequence => IEEE-764 64-bit floating point number
bool
BinTokenReaderTester::readMaybeDouble(Maybe<double>& result)
{
updateLatestKnownGood();
uint8_t bytes[8];
MOZ_ASSERT(sizeof(bytes) == sizeof(double));
if (!readBuf(reinterpret_cast<uint8_t*>(bytes), ArrayLength(bytes)))
return false;
// Decode little-endian.
const uint64_t asInt = LittleEndian::readUint64(bytes);
if (asInt == 0x7FF0000000000001) {
result = Nothing();
} else {
// Canonicalize NaN, just to make sure another form of signalling NaN
// doesn't slip past us.
const double asDouble = CanonicalizeNaN(BitwiseCast<double>(asInt));
result = Some(asDouble);
}
return true;
}
bool
BinTokenReaderTester::readDouble(double& out)
{
Maybe<double> result;
if (!readMaybeDouble(result))
return false;
if (result.isNothing())
return raiseError("Empty double value");
out = *result;
return true;
}
// Internal uint32_t
//
// Encoded as 4 bytes, little-endian.
bool
BinTokenReaderTester::readInternalUint32(uint32_t* result)
{
uint8_t bytes[4];
MOZ_ASSERT(sizeof(bytes) == sizeof(uint32_t));
if (!readBuf(bytes, 4))
return false;
// Decode little-endian.
*result = LittleEndian::readUint32(bytes);
return true;
}
// Nullable strings:
// - "<string>" (not counted in byte length)
// - byte length (not counted in byte length)
// - bytes (UTF-8)
// - "</string>" (not counted in byte length)
//
// The special sequence of bytes `[255, 0]` (which is an invalid UTF-8 sequence)
// is reserved to `null`.
bool
BinTokenReaderTester::readMaybeChars(Maybe<Chars>& out)
{
updateLatestKnownGood();
if (!readConst("<string>"))
return false;
// 1. Read byteLength
uint32_t byteLen;
if (!readInternalUint32(&byteLen))
return false;
// 2. Reject if we can't read
if (current_ + byteLen < current_) // Check for overflows
return raiseError("Arithmetics overflow: string is too long");
if (current_ + byteLen > stop_)
return raiseError("Not enough bytes to read chars");
// 3. Check null string (no allocation)
if (byteLen == 2 && *current_ == 255 && *(current_ + 1) == 0) {
// Special case: null string.
out = Nothing();
current_ += byteLen;
return true;
}
// 4. Other strings (bytes are copied)
out.emplace(cx_);
if (!out->resize(byteLen)) {
ReportOutOfMemory(cx_);
return false;
}
PodCopy(out->begin(), current_, byteLen);
current_ += byteLen;
if (!readConst("</string>"))
return false;
return true;
}
bool
BinTokenReaderTester::readChars(Chars& out)
{
Maybe<Chars> result;
if (!readMaybeChars(result))
return false;
if (result.isNothing())
return raiseError("Empty string");
out = Move(*result);
return true;
}
template <size_t N>
bool
BinTokenReaderTester::matchConst(const char (&value)[N])
{
MOZ_ASSERT(N > 0);
MOZ_ASSERT(value[N - 1] == 0);
MOZ_ASSERT(!cx_->isExceptionPending());
if (current_ + N - 1 > stop_)
return false;
// Perform lookup, without side-effects.
if (!std::equal(current_, current_ + N - 1 /*implicit NUL*/, value))
return false;
// Looks like we have a match. Now perform side-effects
current_ += N - 1;
updateLatestKnownGood();
return true;
}
// Untagged tuple:
// - "<tuple>";
// - contents (specified by the higher-level grammar);
// - "</tuple>"
bool
BinTokenReaderTester::enterUntaggedTuple(AutoTuple& guard)
{
if (!readConst("<tuple>"))
return false;
guard.init();
return true;
}
template <size_t N>
bool
BinTokenReaderTester::readConst(const char (&value)[N])
{
updateLatestKnownGood();
if (!matchConst(value))
return raiseError("Could not find expected literal");
return true;
}
// Tagged tuples:
// - "<tuple>"
// - "<head>"
// - non-null string `name`, followed by \0 (see `readString()`);
// - uint32_t number of fields;
// - array of `number of fields` non-null strings followed each by \0 (see `readString()`);
// - "</head>"
// - content (specified by the higher-level grammar);
// - "</tuple>"
bool
BinTokenReaderTester::enterTaggedTuple(BinKind& tag, BinFields& fields, AutoTaggedTuple& guard)
{
// Header
if (!readConst("<tuple>"))
return false;
if (!readConst("<head>"))
return false;
// This would probably be much faster with a HashTable, but we don't
// really care about the speed of BinTokenReaderTester.
do {
#define FIND_MATCH(CONSTRUCTOR, NAME) \
if (matchConst(#NAME "\0")) { \
tag = BinKind::CONSTRUCTOR; \
break; \
} // else
FOR_EACH_BIN_KIND(FIND_MATCH)
#undef FIND_MATCH
// else
return raiseError("Invalid tag");
} while(false);
// Now fields.
uint32_t fieldNum;
if (!readInternalUint32(&fieldNum))
return false;
fields.clear();
if (!fields.reserve(fieldNum))
return raiseError("Out of memory");
for (uint32_t i = 0; i < fieldNum; ++i) {
// This would probably be much faster with a HashTable, but we don't
// really care about the speed of BinTokenReaderTester.
BinField field;
do {
#define FIND_MATCH(CONSTRUCTOR, NAME) \
if (matchConst(#NAME "\0")) { \
field = BinField::CONSTRUCTOR; \
break; \
} // else
FOR_EACH_BIN_FIELD(FIND_MATCH)
#undef FIND_MATCH
// else
return raiseError("Invalid field");
} while (false);
// Make sure that we do not have duplicate fields.
// Search is linear, but again, we don't really care
// in this implementation.
for (uint32_t j = 0; j < i; ++j) {
if (fields[j] == field) {
return raiseError("Duplicate field");
}
}
fields.infallibleAppend(field); // Already checked.
}
// End of header
if (!readConst("</head>"))
return false;
// Enter the body.
guard.init();
return true;
}
// List:
//
// - "<list>" (not counted in byte length);
// - uint32_t byte length (not counted in byte length);
// - uint32_t number of items;
// - contents (specified by higher-level grammar);
// - "</list>" (not counted in byte length)
//
// The total byte length of `number of items` + `contents` must be `byte length`.
bool
BinTokenReaderTester::enterList(uint32_t& items, AutoList& guard)
{
if (!readConst("<list>"))
return false;
uint32_t byteLen;
if (!readInternalUint32(&byteLen))
return false;
const uint8_t* stop = current_ + byteLen;
if (stop < current_) // Check for overflows
return raiseError("Arithmetics overflow: list is too long");
if (stop > this->stop_)
return raiseError("Incorrect list length");
guard.init(stop);
if (!readInternalUint32(&items))
return false;
return true;
}
void
BinTokenReaderTester::updateLatestKnownGood()
{
MOZ_ASSERT(current_ >= start_);
const size_t update = current_ - start_;
MOZ_ASSERT(update >= latestKnownGoodPos_);
latestKnownGoodPos_ = update;
}
size_t
BinTokenReaderTester::offset() const
{
return latestKnownGoodPos_;
}
TokenPos
BinTokenReaderTester::pos()
{
return pos(latestKnownGoodPos_);
}
TokenPos
BinTokenReaderTester::pos(size_t start)
{
TokenPos pos;
pos.begin = start;
pos.end = current_ - start_;
MOZ_ASSERT(pos.end >= pos.begin);
return pos;
}
void
BinTokenReaderTester::AutoBase::init()
{
initialized_ = true;
}
BinTokenReaderTester::AutoBase::AutoBase(BinTokenReaderTester& reader)
: reader_(reader)
{ }
BinTokenReaderTester::AutoBase::~AutoBase()
{
// By now, the `AutoBase` must have been deinitialized by calling `done()`.
// The only case in which we can accept not calling `done()` is if we have
// bailed out because of an error.
MOZ_ASSERT_IF(initialized_, reader_.cx_->isExceptionPending());
}
bool
BinTokenReaderTester::AutoBase::checkPosition(const uint8_t* expectedEnd)
{
if (reader_.current_ != expectedEnd)
return reader_.raiseError("Caller did not consume the expected set of bytes");
return true;
}
BinTokenReaderTester::AutoList::AutoList(BinTokenReaderTester& reader)
: AutoBase(reader)
{ }
void
BinTokenReaderTester::AutoList::init(const uint8_t* expectedEnd)
{
AutoBase::init();
this->expectedEnd_ = expectedEnd;
}
bool
BinTokenReaderTester::AutoList::done()
{
MOZ_ASSERT(initialized_);
initialized_ = false;
if (reader_.cx_->isExceptionPending()) {
// Already errored, no need to check further.
return false;
}
// Check that we have consumed the exact number of bytes.
if (!checkPosition(expectedEnd_))
return false;
// Check suffix.
if (!reader_.readConst("</list>"))
return false;
return true;
}
BinTokenReaderTester::AutoTaggedTuple::AutoTaggedTuple(BinTokenReaderTester& reader)
: AutoBase(reader)
{ }
bool
BinTokenReaderTester::AutoTaggedTuple::done()
{
MOZ_ASSERT(initialized_);
initialized_ = false;
if (reader_.cx_->isExceptionPending()) {
// Already errored, no need to check further.
return false;
}
// Check suffix.
if (!reader_.readConst("</tuple>"))
return false;
return true;
}
BinTokenReaderTester::AutoTuple::AutoTuple(BinTokenReaderTester& reader)
: AutoBase(reader)
{ }
bool
BinTokenReaderTester::AutoTuple::done()
{
MOZ_ASSERT(initialized_);
initialized_ = false;
if (reader_.cx_->isExceptionPending()) {
// Already errored, no need to check further.
return false;
}
// Check suffix.
if (!reader_.readConst("</tuple>"))
return false;
return true;
}
} // namespace frontend
} // namespace js

View File

@ -1,357 +0,0 @@
#ifndef frontend_BinTokenReaderTester_h
#define frontend_BinTokenReaderTester_h
#include "mozilla/Maybe.h"
#include "frontend/BinToken.h"
#include "frontend/TokenStream.h"
#include "js/TypeDecls.h"
#if !defined(NIGHTLY_BUILD)
#error "BinTokenReaderTester.* is designed to help test implementations of successive versions of JS BinaryAST. It is available only on Nightly."
#endif // !defined(NIGHTLY_BUILD)
namespace js {
namespace frontend {
using namespace mozilla;
using namespace JS;
/**
* A token reader for a simple, alternative serialization format for BinAST.
*
* This serialization format, which is also supported by the reference
* implementation of the BinAST compression suite, is designed to be
* mostly human-readable and easy to check for all sorts of deserialization
* errors. While this format is NOT designed to be shipped to end-users, it
* is nevertheless a very useful tool for implementing and testing parsers.
*
* Both the format and the implementation are ridiculously inefficient:
*
* - the underlying format tags almost all its data with e.g. `<tuple>`, `</tuple>`
* to aid with detecting offset errors or format error;
* - the underlying format copies list of fields into every single node, instead
* of keeping them once in the header;
* - every kind/field extraction requires memory allocation and plenty of string
* comparisons;
* - ...
*
* This token reader is designed to be API-compatible with the standard, shipped,
* token reader. For these reasons:
*
* - it does not support any form of look ahead, push back;
* - it does not support any form of error recovery.
*/
class MOZ_STACK_CLASS BinTokenReaderTester
{
public:
// A list of fields, in the order in which they appear in the stream.
using BinFields = Vector<BinField, 8>;
// A bunch of characters. At this stage, there is no guarantee on whether
// they are valid UTF-8. Future versions may replace this by slice into
// the buffer.
using Chars = Vector<uint8_t, 32>;
class AutoList;
class AutoTuple;
class AutoTaggedTuple;
public:
/**
* Construct a token reader.
*
* Does NOT copy the buffer.
*/
BinTokenReaderTester(JSContext* cx, const uint8_t* start, const size_t length);
/**
* Construct a token reader.
*
* Does NOT copy the buffer.
*/
BinTokenReaderTester(JSContext* cx, const Vector<uint8_t>& chars);
// --- Primitive values.
//
// Note that the underlying format allows for a `null` value for primitive
// values.
//
// Reading will return an error either in case of I/O error or in case of
// a format problem. Reading if an exception in pending is an error and
// will cause assertion failures. Do NOT attempt to read once an exception
// has been cleared: the token reader does NOT support recovery, by design.
/**
* Read a single `true | false | null` value.
*
* @param out Set to `Nothing` if the data specifies that the value is `null`.
* Otherwise, `Some(true)` or `Some(false)`.
*
* @return false If a boolean could not be read. In this case, an error
* has been raised.
*/
MOZ_MUST_USE bool readMaybeBool(Maybe<bool>& out);
MOZ_MUST_USE bool readBool(bool& out);
/**
* Read a single `number | null` value.
*
* @param out Set to `Nothing` if the data specifies that the value is `null`.
* Otherwise, `Some(x)`, where `x` is a valid `double` (i.e. either a non-NaN
* or a canonical NaN).
*
* @return false If a double could not be read. In this case, an error
* has been raised.
*/
MOZ_MUST_USE bool readMaybeDouble(Maybe<double>& out);
MOZ_MUST_USE bool readDouble(double& out);
/**
* Read a single `string | null` value.
*
* @param out Set to `Nothing` if the data specifies that the value is `null`.
* Otherwise, `Some(x)`, where `x` is a `string`.
*
* WARNING: At this stage, the `string` encoding has NOT been validated.
*
* @return false If a string could not be read. In this case, an error
* has been raised.
*/
MOZ_MUST_USE bool readMaybeChars(Maybe<Chars>& out);
MOZ_MUST_USE bool readChars(Chars& out);
// --- Composite values.
//
// The underlying format does NOT allows for a `null` composite value.
//
// Reading will return an error either in case of I/O error or in case of
// a format problem. Reading from a poisoned tokenizer is an error and
// will cause assertion failures.
/**
* Start reading a list.
*
* @param length (OUT) The number of elements in the list.
* @param guard (OUT) A guard, ensuring that we read the list correctly.
*
* The `guard` is dedicated to ensuring that reading the list has consumed
* exactly all the bytes from that list. The `guard` MUST therefore be
* destroyed at the point where the caller has reached the end of the list.
* If the caller has consumed too few/too many bytes, this will be reported
* in the call go `guard.done()`.
*
* @return out If the header of the list is invalid.
*/
MOZ_MUST_USE bool enterList(uint32_t& length, AutoList& guard);
/**
* Start reading a tagged tuple.
*
* @param tag (OUT) The tag of the tuple.
* @param fields (OUT) The ORDERED list of fields encoded in this tuple.
* @param guard (OUT) A guard, ensuring that we read the tagged tuple correctly.
*
* The `guard` is dedicated to ensuring that reading the list has consumed
* exactly all the bytes from that tuple. The `guard` MUST therefore be
* destroyed at the point where the caller has reached the end of the tuple.
* If the caller has consumed too few/too many bytes, this will be reported
* in the call go `guard.done()`.
*
* @return out If the header of the tuple is invalid.
*/
MOZ_MUST_USE bool enterTaggedTuple(BinKind& tag, BinTokenReaderTester::BinFields& fields, AutoTaggedTuple& guard);
/**
* Start reading an untagged tuple.
*
* @param guard (OUT) A guard, ensuring that we read the tuple correctly.
*
* The `guard` is dedicated to ensuring that reading the list has consumed
* exactly all the bytes from that tuple. The `guard` MUST therefore be
* destroyed at the point where the caller has reached the end of the tuple.
* If the caller has consumed too few/too many bytes, this will be reported
* in the call go `guard.done()`.
*
* @return out If the header of the tuple is invalid.
*/
MOZ_MUST_USE bool enterUntaggedTuple(AutoTuple& guard);
/**
* Return the position of the latest token.
*/
TokenPos pos();
TokenPos pos(size_t startOffset);
size_t offset() const;
/**
* Raise an error.
*
* Once `raiseError` has been called, the tokenizer is poisoned.
*/
MOZ_MUST_USE bool raiseError(const char* description);
/**
* Poison this tokenizer.
*/
void poison();
private:
/**
* Read a single byte.
*/
MOZ_MUST_USE bool readByte(uint8_t* byte);
/**
* Read several bytes.
*
* If there is not enough data, or if the tokenizer has previously been
* poisoned, return `false` and report an exception.
*/
MOZ_MUST_USE bool readBuf(uint8_t* bytes, uint32_t len);
/**
* Read a single uint32_t.
*/
MOZ_MUST_USE bool readInternalUint32(uint32_t*);
/**
* Read a sequence of chars, ensuring that they match an expected
* sequence of chars.
*
* @param value The sequence of chars to expect, NUL-terminated. The NUL
* is not expected in the stream.
*/
template <size_t N>
MOZ_MUST_USE bool readConst(const char (&value)[N]);
/**
* Read a sequence of chars, consuming the bytes only if they match an expected
* sequence of chars.
*
* @param value The sequence of chars to expect, NUL-terminated. The NUL
* is not expected in the stream.
* @return true if `value` (minus NUL) represents the next few chars in the
* internal buffer, false otherwise. If `true`, the chars are consumed,
* otherwise there is no side-effect.
*/
template <size_t N>
MOZ_MUST_USE bool matchConst(const char (&value)[N]);
/**
* Update the "latest known good" position, which is used during error
* reporting.
*/
void updateLatestKnownGood();
private:
JSContext* cx_;
// `true` if we have encountered an error. Errors are non recoverable.
// Attempting to read from a poisoned tokenizer will cause assertion errors.
bool poisoned_;
// The first byte of the buffer. Not owned.
const uint8_t* start_;
// The current position.
const uint8_t* current_;
// The last+1 byte of the buffer.
const uint8_t* stop_;
// Latest known good position. Used for error reporting.
size_t latestKnownGoodPos_;
BinTokenReaderTester(const BinTokenReaderTester&) = delete;
BinTokenReaderTester(BinTokenReaderTester&&) = delete;
BinTokenReaderTester& operator=(BinTokenReaderTester&) = delete;
public:
// The following classes are used whenever we encounter a tuple/tagged tuple/list
// to make sure that:
//
// - if the construct "knows" its byte length, we have exactly consumed all
// the bytes (otherwise, this means that the file is corrupted, perhaps on
// purpose, so we need to reject the stream);
// - if the construct has a footer, once we are done reading it, we have
// reached the footer (this is to aid with debugging).
//
// In either case, the caller MUST call method `done()` of the guard once
// it is done reading the tuple/tagged tuple/list, to report any pending error.
// Base class used by other Auto* classes.
class MOZ_STACK_CLASS AutoBase
{
protected:
explicit AutoBase(BinTokenReaderTester& reader);
~AutoBase();
// Raise an error if we are not in the expected position.
MOZ_MUST_USE bool checkPosition(const uint8_t* expectedPosition);
friend BinTokenReaderTester;
void init();
// Set to `true` if `init()` has been called. Reset to `false` once
// all conditions have been checked.
bool initialized_;
BinTokenReaderTester& reader_;
};
// Guard class used to ensure that `enterList` is used properly.
class MOZ_STACK_CLASS AutoList : public AutoBase
{
public:
explicit AutoList(BinTokenReaderTester& reader);
// Check that we have properly read to the end of the list.
MOZ_MUST_USE bool done();
protected:
friend BinTokenReaderTester;
void init(const uint8_t* expectedEnd);
private:
const uint8_t* expectedEnd_;
};
// Guard class used to ensure that `enterTaggedTuple` is used properly.
class MOZ_STACK_CLASS AutoTaggedTuple : public AutoBase
{
public:
explicit AutoTaggedTuple(BinTokenReaderTester& reader);
// Check that we have properly read to the end of the tuple.
MOZ_MUST_USE bool done();
};
// Guard class used to ensure that `readTuple` is used properly.
class MOZ_STACK_CLASS AutoTuple : public AutoBase
{
public:
explicit AutoTuple(BinTokenReaderTester& reader);
// Check that we have properly read to the end of the tuple.
MOZ_MUST_USE bool done();
};
// Compare a `Chars` and a string literal (ONLY a string literal).
template <size_t N>
static bool equals(const Chars& left, const char (&right)[N]) {
MOZ_ASSERT(N > 0);
MOZ_ASSERT(right[N - 1] == 0);
if (left.length() + 1 /* implicit NUL */ != N)
return false;
if (!std::equal(left.begin(), left.end(), right))
return false;
return true;
}
};
} // namespace frontend
} // namespace js
#endif // frontend_BinTokenReaderTester_h

View File

@ -124,14 +124,6 @@ IsKeyword(JSLinearString* str);
void
TraceParser(JSTracer* trc, JS::AutoGCRooter* parser);
#if defined(JS_BUILD_BINAST)
/* Trace all GC things reachable from binjs parser. Defined in BinSource.cpp. */
void
TraceBinParser(JSTracer* trc, JS::AutoGCRooter* parser);
#endif // defined(JS_BUILD_BINAST)
class MOZ_STACK_CLASS AutoFrontendTraceLog
{
#ifdef JS_TRACE_LOGGING

View File

@ -21,13 +21,6 @@ class RegExpObject;
namespace frontend {
enum class SourceKind {
// We are parsing from a text source (Parser.h)
Text,
// We are parsing from a binary source (BinSource.h)
Binary,
};
// Parse handler used when generating a full parse tree for all code which the
// parser encounters.
class FullParseHandler
@ -48,8 +41,6 @@ class FullParseHandler
size_t lazyInnerFunctionIndex;
size_t lazyClosedOverBindingIndex;
const SourceKind sourceKind_;
public:
/* new_ methods for creating parse nodes. These report OOM on context. */
JS_DECLARE_NEW_METHODS(new_, allocParseNode, inline)
@ -77,24 +68,15 @@ class FullParseHandler
return node->isInParens() && (node->isKind(PNK_OBJECT) || node->isKind(PNK_ARRAY));
}
FullParseHandler(JSContext* cx, LifoAlloc& alloc, LazyScript* lazyOuterFunction,
SourceKind kind = SourceKind::Text)
FullParseHandler(JSContext* cx, LifoAlloc& alloc, LazyScript* lazyOuterFunction)
: allocator(cx, alloc),
lazyOuterFunction_(cx, lazyOuterFunction),
lazyInnerFunctionIndex(0),
lazyClosedOverBindingIndex(0),
sourceKind_(SourceKind::Text)
lazyClosedOverBindingIndex(0)
{}
static ParseNode* null() { return nullptr; }
// The FullParseHandler may be used to create nodes for text sources
// (from Parser.h) or for binary sources (from BinSource.h). In the latter
// case, some common assumptions on offsets are incorrect, e.g. in `a + b`,
// `a`, `b` and `+` may be stored in any order. We use `sourceKind()`
// to determine whether we need to check these assumptions.
SourceKind sourceKind() const { return sourceKind_; }
ParseNode* freeTree(ParseNode* pn) { return allocator.freeTree(pn); }
void prepareNodeForMutation(ParseNode* pn) { return allocator.prepareNodeForMutation(pn); }
@ -248,7 +230,8 @@ class FullParseHandler
ParseNode* elision = new_<NullaryNode>(PNK_ELISION, pos);
if (!elision)
return false;
addList(/* list = */ literal, /* child = */ elision);
literal->append(elision);
literal->pn_xflags |= PNX_ARRAYHOLESPREAD | PNX_NONCONST;
return true;
}
@ -260,7 +243,8 @@ class FullParseHandler
ParseNode* spread = newSpread(begin, inner);
if (!spread)
return false;
addList(/* list = */ literal, /* child = */ spread);
literal->append(spread);
literal->pn_xflags |= PNX_ARRAYHOLESPREAD | PNX_NONCONST;
return true;
}
@ -270,7 +254,8 @@ class FullParseHandler
if (!element->isConstant())
literal->pn_xflags |= PNX_NONCONST;
addList(/* list = */ literal, /* child = */ element);
literal->append(element);
}
ParseNode* newCall(const TokenPos& pos) {
@ -309,9 +294,7 @@ class FullParseHandler
ParseNode* newSuperBase(ParseNode* thisName, const TokenPos& pos) {
return new_<UnaryNode>(PNK_SUPERBASE, pos, thisName);
}
ParseNode* newCatchBlock(ParseNode* catchName, ParseNode* catchGuard, ParseNode* catchBody) {
return new_<TernaryNode>(PNK_CATCH, catchName, catchGuard, catchBody);
}
MOZ_MUST_USE bool addPrototypeMutation(ParseNode* literal, uint32_t begin, ParseNode* expr) {
MOZ_ASSERT(literal->isKind(PNK_OBJECT));
MOZ_ASSERT(literal->isArity(PN_LIST));
@ -323,19 +306,22 @@ class FullParseHandler
ParseNode* mutation = newUnary(PNK_MUTATEPROTO, begin, expr);
if (!mutation)
return false;
addList(/* list = */ literal, /* child = */ mutation);
literal->append(mutation);
return true;
}
MOZ_MUST_USE bool addPropertyDefinition(ParseNode* literal, ParseNode* key, ParseNode* val) {
MOZ_ASSERT(literal->isKind(PNK_OBJECT));
MOZ_ASSERT(literal->isArity(PN_LIST));
MOZ_ASSERT(isUsableAsObjectPropertyName(key));
MOZ_ASSERT(key->isKind(PNK_NUMBER) ||
key->isKind(PNK_OBJECT_PROPERTY_NAME) ||
key->isKind(PNK_STRING) ||
key->isKind(PNK_COMPUTED_NAME));
ParseNode* propdef = newBinary(PNK_COLON, key, val, JSOP_INITPROP);
if (!propdef)
return false;
addList(/* list = */ literal, /* child = */ propdef);
literal->append(propdef);
return true;
}
@ -350,7 +336,7 @@ class FullParseHandler
ParseNode* propdef = newBinary(PNK_SHORTHAND, name, expr, JSOP_INITPROP);
if (!propdef)
return false;
addList(/* list = */ literal, /* child = */ propdef);
literal->append(propdef);
return true;
}
@ -362,21 +348,26 @@ class FullParseHandler
ParseNode* spread = newSpread(begin, inner);
if (!spread)
return false;
addList(/* list = */ literal, /* child = */ spread);
literal->append(spread);
return true;
}
MOZ_MUST_USE bool addObjectMethodDefinition(ParseNode* literal, ParseNode* key, ParseNode* fn,
AccessorType atype)
{
MOZ_ASSERT(literal->isKind(PNK_OBJECT));
MOZ_ASSERT(literal->isArity(PN_LIST));
literal->pn_xflags |= PNX_NONCONST;
MOZ_ASSERT(key->isKind(PNK_NUMBER) ||
key->isKind(PNK_OBJECT_PROPERTY_NAME) ||
key->isKind(PNK_STRING) ||
key->isKind(PNK_COMPUTED_NAME));
ParseNode* propdef = newObjectMethodOrPropertyDefinition(key, fn, atype);
ParseNode* propdef = newBinary(PNK_COLON, key, fn, AccessorTypeToJSOp(atype));
if (!propdef)
return false;
addList(/* list = */ literal, /* child = */ propdef);
literal->append(propdef);
literal->pn_xflags |= PNX_NONCONST;
return true;
}
@ -384,12 +375,15 @@ class FullParseHandler
AccessorType atype, bool isStatic)
{
MOZ_ASSERT(methodList->isKind(PNK_CLASSMETHODLIST));
MOZ_ASSERT(isUsableAsObjectPropertyName(key));
MOZ_ASSERT(key->isKind(PNK_NUMBER) ||
key->isKind(PNK_OBJECT_PROPERTY_NAME) ||
key->isKind(PNK_STRING) ||
key->isKind(PNK_COMPUTED_NAME));
ParseNode* classMethod = new_<ClassMethod>(key, fn, AccessorTypeToJSOp(atype), isStatic);
if (!classMethod)
return false;
addList(/* list = */ methodList, /* child = */ classMethod);
methodList->append(classMethod);
return true;
}
@ -428,7 +422,7 @@ class FullParseHandler
void addStatementToList(ParseNode* list, ParseNode* stmt) {
MOZ_ASSERT(list->isKind(PNK_STATEMENTLIST));
addList(/* list = */ list, /* child = */ stmt);
list->append(stmt);
if (isFunctionStmt(stmt)) {
// PNX_FUNCDEFS notifies the emitter that the block contains
@ -448,16 +442,12 @@ class FullParseHandler
MOZ_ASSERT(casepn->isKind(PNK_CASE));
MOZ_ASSERT(casepn->pn_right->isKind(PNK_STATEMENTLIST));
addList(/* list = */ list, /* child = */ casepn);
list->append(casepn);
if (casepn->pn_right->pn_xflags & PNX_FUNCDEFS)
list->pn_xflags |= PNX_FUNCDEFS;
}
MOZ_MUST_USE inline bool addCatchBlock(ParseNode* catchList, ParseNode* lexicalScope,
ParseNode* catchName, ParseNode* catchGuard,
ParseNode* catchBody);
MOZ_MUST_USE bool prependInitialYield(ParseNode* stmtList, ParseNode* genName) {
MOZ_ASSERT(stmtList->isKind(PNK_STATEMENTLIST));
MOZ_ASSERT(stmtList->isArity(PN_LIST));
@ -469,7 +459,8 @@ class FullParseHandler
MOZ_ASSERT(genName->getOp() == JSOP_GETNAME);
genName->setOp(JSOP_SETNAME);
ParseNode* genInit = newAssignment(PNK_ASSIGN, /* lhs = */ genName, /* rhs = */ makeGen);
ParseNode* genInit = newBinary(PNK_ASSIGN, genName, makeGen);
if (!genInit)
return false;
@ -680,20 +671,6 @@ class FullParseHandler
!node->pn_funbox->isArrow();
}
ParseNode* newObjectMethodOrPropertyDefinition(ParseNode* key, ParseNode* fn, AccessorType atype) {
MOZ_ASSERT(isUsableAsObjectPropertyName(key));
return newBinary(PNK_COLON, key, fn, AccessorTypeToJSOp(atype));
}
bool setComprehensionLambdaBody(ParseNode* pn, ParseNode* body) {
MOZ_ASSERT(body->isKind(PNK_STATEMENTLIST));
ParseNode* paramsBody = newList(PNK_PARAMSBODY, body);
if (!paramsBody)
return false;
setFunctionFormalParametersAndBody(pn, paramsBody);
return true;
}
void setFunctionFormalParametersAndBody(ParseNode* funcNode, ParseNode* kid) {
MOZ_ASSERT_IF(kid, kid->isKind(PNK_PARAMSBODY));
funcNode->pn_body = kid;
@ -704,11 +681,11 @@ class FullParseHandler
funbox->functionNode = pn;
}
void addFunctionFormalParameter(ParseNode* pn, ParseNode* argpn) {
addList(/* list = */ pn->pn_body, /* child = */ argpn);
pn->pn_body->append(argpn);
}
void setFunctionBody(ParseNode* fn, ParseNode* body) {
MOZ_ASSERT(fn->pn_body->isKind(PNK_PARAMSBODY));
addList(/* list = */ fn->pn_body, /* child = */ body);
fn->pn_body->append(body);
}
ParseNode* newModule(const TokenPos& pos) {
@ -724,7 +701,7 @@ class FullParseHandler
if (!newExpr)
return nullptr;
addList(/* list = */ newExpr, /* child = */ ctor);
addList(newExpr, ctor);
return newExpr;
}
@ -767,13 +744,6 @@ class FullParseHandler
return node->isKind(PNK_SUPERBASE);
}
bool isUsableAsObjectPropertyName(ParseNode* node) {
return node->isKind(PNK_NUMBER)
|| node->isKind(PNK_OBJECT_PROPERTY_NAME)
|| node->isKind(PNK_STRING)
|| node->isKind(PNK_COMPUTED_NAME);
}
inline MOZ_MUST_USE bool finishInitializerAssignment(ParseNode* pn, ParseNode* init);
void setBeginPosition(ParseNode* pn, ParseNode* oth) {
@ -835,10 +805,7 @@ class FullParseHandler
}
void addList(ParseNode* list, ParseNode* kid) {
if (sourceKind_ == SourceKind::Text)
list->append(kid);
else
list->appendWithoutOrderAssumption(kid);
list->append(kid);
}
void setOp(ParseNode* pn, JSOp op) {
@ -912,19 +879,6 @@ class FullParseHandler
}
};
inline bool
FullParseHandler::addCatchBlock(ParseNode* catchList, ParseNode* lexicalScope,
ParseNode* catchName, ParseNode* catchGuard,
ParseNode* catchBody)
{
ParseNode* catchpn = newCatchBlock(catchName, catchGuard, catchBody);
if (!catchpn)
return false;
addList(/* list = */ catchList, /* child = */ lexicalScope);
lexicalScope->setScopeBody(catchpn);
return true;
}
inline bool
FullParseHandler::setLastFunctionFormalParameterDefault(ParseNode* funcpn,
ParseNode* defaultValue)

View File

@ -1,96 +0,0 @@
#ifndef frontend_ParseContext_inl_h
#define frontend_ParseContext_inl_h
#include "frontend/ParseContext.h"
namespace js {
namespace frontend {
template <>
inline bool
ParseContext::Statement::is<ParseContext::LabelStatement>() const
{
return kind_ == StatementKind::Label;
}
template <>
inline bool
ParseContext::Statement::is<ParseContext::ClassStatement>() const
{
return kind_ == StatementKind::Class;
}
inline JS::Result<Ok, ParseContext::BreakStatementError>
ParseContext::checkBreakStatement(PropertyName* label)
{
// Labeled 'break' statements target the nearest labeled statements (could
// be any kind) with the same label. Unlabeled 'break' statements target
// the innermost loop or switch statement.
if (label) {
auto hasSameLabel = [&label](ParseContext::LabelStatement* stmt) {
MOZ_ASSERT(stmt);
return stmt->label() == label;
};
if (!findInnermostStatement<ParseContext::LabelStatement>(hasSameLabel))
return mozilla::Err(ParseContext::BreakStatementError::LabelNotFound);
} else {
auto isBreakTarget = [](ParseContext::Statement* stmt) {
return StatementKindIsUnlabeledBreakTarget(stmt->kind());
};
if (!findInnermostStatement(isBreakTarget))
return mozilla::Err(ParseContext::BreakStatementError::ToughBreak);
}
return Ok();
}
inline JS::Result<Ok, ParseContext::ContinueStatementError>
ParseContext::checkContinueStatement(PropertyName* label)
{
// Labeled 'continue' statements target the nearest labeled loop
// statements with the same label. Unlabeled 'continue' statements target
// the innermost loop statement.
auto isLoop = [](ParseContext::Statement* stmt) {
MOZ_ASSERT(stmt);
return StatementKindIsLoop(stmt->kind());
};
if (!label) {
// Unlabeled statement: we target the innermost loop, so make sure that
// there is an innermost loop.
if (!findInnermostStatement(isLoop))
return mozilla::Err(ParseContext::ContinueStatementError::NotInALoop);
return Ok();
}
// Labeled statement: targest the nearest labeled loop with the same label.
ParseContext::Statement* stmt = innermostStatement();
bool foundLoop = false; // True if we have encountered at least one loop.
for (;;) {
stmt = ParseContext::Statement::findNearest(stmt, isLoop);
if (!stmt)
return foundLoop ? mozilla::Err(ParseContext::ContinueStatementError::LabelNotFound)
: mozilla::Err(ParseContext::ContinueStatementError::NotInALoop);
foundLoop = true;
// Is it labeled by our label?
stmt = stmt->enclosing();
while (stmt && stmt->is<ParseContext::LabelStatement>()) {
if (stmt->as<ParseContext::LabelStatement>().label() == label)
return Ok();
stmt = stmt->enclosing();
}
}
}
}
}
#endif // frontend_ParseContext_inl_h

View File

@ -7,11 +7,7 @@
#ifndef frontend_ParseContext_h
#define frontend_ParseContext_h
#include "ds/Nestable.h"
#include "frontend/BytecodeCompiler.h"
#include "frontend/ErrorReporter.h"
#include "frontend/SharedContext.h"
namespace js {
@ -293,10 +289,6 @@ class ParseContext : public Nestable<ParseContext>
return declared_.acquire(pc->sc()->context);
}
bool isEmpty() const {
return declared_->all().empty();
}
DeclaredNamePtr lookupDeclaredName(JSAtom* name) {
return declared_->lookup(name);
}
@ -410,7 +402,6 @@ class ParseContext : public Nestable<ParseContext>
{
public:
explicit inline VarScope(ParserBase* parser);
explicit inline VarScope(JSContext* cx, ParseContext* pc, UsedNameTracker& usedNames);
};
private:
@ -526,7 +517,6 @@ class ParseContext : public Nestable<ParseContext>
return sc_;
}
// `true` if we are in the body of a function definition.
bool isFunctionBox() const {
return sc_->isFunctionBox();
}
@ -588,22 +578,6 @@ class ParseContext : public Nestable<ParseContext>
return *closedOverBindingsForLazy_;
}
enum class BreakStatementError {
// Unlabeled break must be inside loop or switch.
ToughBreak,
LabelNotFound,
};
// Return Err(true) if we have encountered at least one loop,
// Err(false) otherwise.
MOZ_MUST_USE inline JS::Result<Ok, BreakStatementError> checkBreakStatement(PropertyName* label);
enum class ContinueStatementError {
NotInALoop,
LabelNotFound,
};
MOZ_MUST_USE inline JS::Result<Ok, ContinueStatementError> checkContinueStatement(PropertyName* label);
// True if we are at the topmost level of a entire script or function body.
// For example, while parsing this code we would encounter f1 and f2 at
// body level, but we would not encounter f3 or f4 at body level:

View File

@ -13,27 +13,6 @@
#include "frontend/TokenStream.h"
#include "vm/Printer.h"
// A few notes on lifetime of ParseNode trees:
//
// - All the `ParseNode` instances MUST BE explicitly allocated in the context's `LifoAlloc`.
// This is typically implemented by the `FullParseHandler` or it can be reimplemented with
// a custom `new_`.
//
// - The tree is bulk-deallocated when the parser is deallocated. Consequently, references
// to a subtree MUST NOT exist once the parser has been deallocated.
//
// - This bulk-deallocation DOES NOT run destructors.
//
// - Instances of `LexicalScope::Data` MUST BE allocated as instances of `ParseNode`, in the same
// `LifoAlloc`. They are bulk-deallocated alongside the rest of the tree.
//
// - Instances of `JSAtom` used throughout the tree (including instances of `PropertyName`) MUST
// be kept alive by the parser. This is done through an instance of `AutoKeepAtoms` held by
// the parser.
//
// - Once the parser is deallocated, the `JSAtom` instances MAY be garbage-collected.
namespace js {
namespace frontend {
@ -619,7 +598,6 @@ class ParseNode
appendOrCreateList(ParseNodeKind kind, ParseNode* left, ParseNode* right,
FullParseHandler* handler, ParseContext* pc);
// include "ParseNode-inl.h" for these methods.
inline PropertyName* name() const;
inline JSAtom* atom() const;
@ -753,12 +731,8 @@ class ParseNode
}
void append(ParseNode* pn) {
MOZ_ASSERT(pn->pn_pos.begin >= pn_pos.begin);
appendWithoutOrderAssumption(pn);
}
void appendWithoutOrderAssumption(ParseNode* pn) {
MOZ_ASSERT(pn_arity == PN_LIST);
MOZ_ASSERT(pn->pn_pos.begin >= pn_pos.begin);
pn_pos.end = pn->pn_pos.end;
*pn_tail = pn;
pn_tail = &pn->pn_next;

View File

@ -43,7 +43,6 @@
#include "jsatominlines.h"
#include "jsscriptinlines.h"
#include "frontend/ParseContext-inl.h"
#include "frontend/ParseNode-inl.h"
#include "vm/EnvironmentObject-inl.h"
@ -1720,7 +1719,7 @@ Parser<FullParseHandler, CharT>::checkStatementsEOF()
}
template <typename Scope>
typename Scope::Data*
static typename Scope::Data*
NewEmptyBindingData(JSContext* cx, LifoAlloc& alloc, uint32_t numBindings)
{
size_t allocSize = Scope::sizeOfData(numBindings);
@ -1734,9 +1733,8 @@ NewEmptyBindingData(JSContext* cx, LifoAlloc& alloc, uint32_t numBindings)
}
Maybe<GlobalScope::Data*>
NewGlobalScopeData(JSContext* context, ParseContext::Scope& scope, LifoAlloc& alloc, ParseContext* pc)
ParserBase::newGlobalScopeData(ParseContext::Scope& scope)
{
Vector<BindingName> funs(context);
Vector<BindingName> vars(context);
Vector<BindingName> lets(context);
@ -1799,14 +1797,8 @@ NewGlobalScopeData(JSContext* context, ParseContext::Scope& scope, LifoAlloc& al
return Some(bindings);
}
Maybe<GlobalScope::Data*>
ParserBase::newGlobalScopeData(ParseContext::Scope& scope)
{
return NewGlobalScopeData(context, scope, alloc, pc);
}
Maybe<ModuleScope::Data*>
NewModuleScopeData(JSContext* context, ParseContext::Scope& scope, LifoAlloc& alloc, ParseContext* pc)
ParserBase::newModuleScopeData(ParseContext::Scope& scope)
{
Vector<BindingName> imports(context);
Vector<BindingName> vars(context);
@ -1871,14 +1863,8 @@ NewModuleScopeData(JSContext* context, ParseContext::Scope& scope, LifoAlloc& al
return Some(bindings);
}
Maybe<ModuleScope::Data*>
ParserBase::newModuleScopeData(ParseContext::Scope& scope)
{
return NewModuleScopeData(context, scope, alloc, pc);
}
Maybe<EvalScope::Data*>
NewEvalScopeData(JSContext* context, ParseContext::Scope& scope, LifoAlloc& alloc, ParseContext* pc)
ParserBase::newEvalScopeData(ParseContext::Scope& scope)
{
Vector<BindingName> funs(context);
Vector<BindingName> vars(context);
@ -1921,14 +1907,8 @@ NewEvalScopeData(JSContext* context, ParseContext::Scope& scope, LifoAlloc& allo
return Some(bindings);
}
Maybe<EvalScope::Data*>
ParserBase::newEvalScopeData(ParseContext::Scope& scope)
{
return NewEvalScopeData(context, scope, alloc, pc);
}
Maybe<FunctionScope::Data*>
NewFunctionScopeData(JSContext* context, ParseContext::Scope& scope, bool hasParameterExprs, LifoAlloc& alloc, ParseContext* pc)
ParserBase::newFunctionScopeData(ParseContext::Scope& scope, bool hasParameterExprs)
{
Vector<BindingName> positionalFormals(context);
Vector<BindingName> formals(context);
@ -2021,14 +2001,8 @@ NewFunctionScopeData(JSContext* context, ParseContext::Scope& scope, bool hasPar
return Some(bindings);
}
Maybe<FunctionScope::Data*>
ParserBase::newFunctionScopeData(ParseContext::Scope& scope, bool hasParameterExprs)
{
return NewFunctionScopeData(context, scope, hasParameterExprs, alloc, pc);
}
Maybe<VarScope::Data*>
NewVarScopeData(JSContext* context, ParseContext::Scope& scope, LifoAlloc& alloc, ParseContext* pc)
ParserBase::newVarScopeData(ParseContext::Scope& scope)
{
Vector<BindingName> vars(context);
@ -2059,14 +2033,8 @@ NewVarScopeData(JSContext* context, ParseContext::Scope& scope, LifoAlloc& alloc
return Some(bindings);
}
Maybe<VarScope::Data*>
ParserBase::newVarScopeData(ParseContext::Scope& scope)
{
return NewVarScopeData(context, scope, alloc, pc);
}
Maybe<LexicalScope::Data*>
NewLexicalScopeData(JSContext* context, ParseContext::Scope& scope, LifoAlloc& alloc, ParseContext* pc)
ParserBase::newLexicalScopeData(ParseContext::Scope& scope)
{
Vector<BindingName> lets(context);
Vector<BindingName> consts(context);
@ -2116,12 +2084,6 @@ NewLexicalScopeData(JSContext* context, ParseContext::Scope& scope, LifoAlloc& a
return Some(bindings);
}
Maybe<LexicalScope::Data*>
ParserBase::newLexicalScopeData(ParseContext::Scope& scope)
{
return NewLexicalScopeData(context, scope, alloc, pc);
}
template <typename CharT>
SyntaxParseHandler::Node
Parser<SyntaxParseHandler, CharT>::finishLexicalScope(ParseContext::Scope& scope, Node body)
@ -6586,16 +6548,44 @@ GeneralParser<ParseHandler, CharT>::continueStatement(YieldHandling yieldHandlin
if (!matchLabel(yieldHandling, &label))
return null();
auto validity = pc->checkContinueStatement(label);
if (validity.isErr()) {
switch (validity.unwrapErr()) {
case ParseContext::ContinueStatementError::NotInALoop:
errorAt(begin, JSMSG_BAD_CONTINUE);
break;
case ParseContext::ContinueStatementError::LabelNotFound:
error(JSMSG_LABEL_NOT_FOUND);
break;
// Labeled 'continue' statements target the nearest labeled loop
// statements with the same label. Unlabeled 'continue' statements target
// the innermost loop statement.
auto isLoop = [](ParseContext::Statement* stmt) {
return StatementKindIsLoop(stmt->kind());
};
if (label) {
ParseContext::Statement* stmt = pc->innermostStatement();
bool foundLoop = false;
for (;;) {
stmt = ParseContext::Statement::findNearest(stmt, isLoop);
if (!stmt) {
if (foundLoop)
error(JSMSG_LABEL_NOT_FOUND);
else
errorAt(begin, JSMSG_BAD_CONTINUE);
return null();
}
foundLoop = true;
// Is it labeled by our label?
bool foundTarget = false;
stmt = stmt->enclosing();
while (stmt && stmt->is<ParseContext::LabelStatement>()) {
if (stmt->as<ParseContext::LabelStatement>().label() == label) {
foundTarget = true;
break;
}
stmt = stmt->enclosing();
}
if (foundTarget)
break;
}
} else if (!pc->findInnermostStatement(isLoop)) {
error(JSMSG_BAD_CONTINUE);
return null();
}

View File

@ -49,6 +49,20 @@ public:
{ }
};
template <>
inline bool
ParseContext::Statement::is<ParseContext::LabelStatement>() const
{
return kind_ == StatementKind::Label;
}
template <>
inline bool
ParseContext::Statement::is<ParseContext::ClassStatement>() const
{
return kind_ == StatementKind::Class;
}
template <typename T>
inline T&
ParseContext::Statement::as()
@ -257,13 +271,6 @@ ParseContext::VarScope::VarScope(ParserBase* parser)
useAsVarScope(parser->pc);
}
inline
ParseContext::VarScope::VarScope(JSContext* cx, ParseContext* pc, UsedNameTracker& usedNames)
: Scope(cx, pc, usedNames)
{
useAsVarScope(pc);
}
enum class ExpressionClosure { Allowed, Forbidden };
template<class Parser>
@ -1282,21 +1289,6 @@ class MOZ_STACK_CLASS AutoAwaitIsKeyword
}
};
template <typename Scope>
extern typename Scope::Data*
NewEmptyBindingData(JSContext* cx, LifoAlloc& alloc, uint32_t numBindings);
Maybe<GlobalScope::Data*>
NewGlobalScopeData(JSContext* context, ParseContext::Scope& scope, LifoAlloc& alloc, ParseContext* pc);
Maybe<EvalScope::Data*>
NewEvalScopeData(JSContext* context, ParseContext::Scope& scope, LifoAlloc& alloc, ParseContext* pc);
Maybe<FunctionScope::Data*>
NewFunctionScopeData(JSContext* context, ParseContext::Scope& scope, bool hasParameterExprs, LifoAlloc& alloc, ParseContext* pc);
Maybe<VarScope::Data*>
NewVarScopeData(JSContext* context, ParseContext::Scope& scope, LifoAlloc& alloc, ParseContext* pc);
Maybe<LexicalScope::Data*>
NewLexicalScopeData(JSContext* context, ParseContext::Scope& scope, LifoAlloc& alloc, ParseContext* pc);
} /* namespace frontend */
} /* namespace js */

View File

@ -15,14 +15,12 @@
#include "builtin/ModuleObject.h"
#include "ds/InlineTable.h"
#include "frontend/ParseNode.h"
#include "frontend/TokenStream.h"
#include "vm/EnvironmentObject.h"
namespace js {
namespace frontend {
class ParseContext;
class ParseNode;
enum class StatementKind : uint8_t

View File

@ -153,12 +153,6 @@ AutoGCRooter::trace(JSTracer* trc)
frontend::TraceParser(trc, this);
return;
#if defined(JS_BUILD_BINAST)
case BINPARSER:
frontend::TraceBinParser(trc, this);
return;
#endif // defined(JS_BUILD_BINAST)
case VALARRAY: {
/*
* We don't know the template size parameter, but we can safely treat it

View File

@ -2323,8 +2323,7 @@ BoyerMoorePositionInfo::SetInterval(const Interval& interval)
}
return;
}
MOZ_ASSERT(interval.from() <= interval.to());
for (int i = interval.from(); i != interval.to() + 1; i++) {
for (int i = interval.from(); i <= interval.to(); i++) {
int mod_character = (i & kMask);
if (!map_[mod_character]) {
map_count_++;

View File

@ -1,73 +0,0 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
* File Name: StrictEquality-001.js
* ECMA Section: 11.9.6.js
* Description:
*
* Author: christine@netscape.com
* Date: 4 september 1998
*/
var SECTION = "StrictEquality-001 - 11.9.6";
var VERSION = "ECMA_2";
var TITLE = "The strict equality operator ( === )";
startTest();
writeHeaderToLog( SECTION + " "+ TITLE);
// 1. If Type(x) is different from Type(y) return false
StrictEquality( true, new Boolean(true), false );
StrictEquality( new Boolean(), false, false );
StrictEquality( "", new String(), false );
StrictEquality( new String("hi"), "hi", false );
// 2. If Type(x) is not Number go to step 9.
// 3. If x is NaN, return false
StrictEquality( NaN, NaN, false );
StrictEquality( NaN, 0, false );
// 4. If y is NaN, return false.
StrictEquality( 0, NaN, false );
// 5. if x is the same number value as y, return true
// 6. If x is +0 and y is -0, return true
// 7. If x is -0 and y is +0, return true
// 8. Return false.
// 9. If Type(x) is String, then return true if x and y are exactly
// the same sequence of characters ( same length and same characters
// in corresponding positions.) Otherwise return false.
// 10. If Type(x) is Boolean, return true if x and y are both true or
// both false. otherwise return false.
// Return true if x and y refer to the same object. Otherwise return
// false.
// Return false.
test();
function StrictEquality( x, y, expect ) {
result = ( x === y );
new TestCase(
SECTION,
x +" === " + y,
expect,
result );
}

View File

@ -1,29 +0,0 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 4 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
print("STATUS: f.apply crash test.");
print("BUGNUMBER: 21836");
function f ()
{
}
var SECTION = "apply-001-n";
var VERSION = "ECMA_1";
startTest();
var TITLE = "f.apply(2,2) doesn't crash";
writeHeaderToLog( SECTION + " "+ TITLE);
DESCRIPTION = "f.apply(2,2) doesn't crash";
EXPECTED = "error";
new TestCase( SECTION, "f.apply(2,2) doesn't crash", "error", eval("f.apply(2,2)") );
test();

View File

@ -1,47 +0,0 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
File Name: boolean-001.js
Description: Corresponds to ecma/Boolean/15.6.4.2-4-n.js
The toString function is not generic; it generates
a runtime error if its this value is not a Boolean
object. Therefore it cannot be transferred to other
kinds of objects for use as a method.
Author: christine@netscape.com
Date: june 27, 1997
*/
var SECTION = "boolean-001.js";
var VERSION = "JS1_4";
var TITLE = "Boolean.prototype.toString()";
startTest();
writeHeaderToLog( SECTION +" "+ TITLE );
var exception = "No exception thrown";
var result = "Failed";
var TO_STRING = Boolean.prototype.toString;
try {
var s = new String("Not a Boolean");
s.toString = TO_STRING;
s.toString();
} catch ( e ) {
result = "Passed!";
exception = e.toString();
}
new TestCase(
SECTION,
"Assigning Boolean.prototype.toString to a String object "+
"(threw " +exception +")",
"Passed!",
result );
test();

View File

@ -1,51 +0,0 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
File Name: boolean-001.js
Description: Corresponds to ecma/Boolean/15.6.4.3-4-n.js
15.6.4.3 Boolean.prototype.valueOf()
Returns this boolean value.
The valueOf function is not generic; it generates
a runtime error if its this value is not a Boolean
object. Therefore it cannot be transferred to other
kinds of objects for use as a method.
Author: christine@netscape.com
Date: 09 september 1998
*/
var SECTION = "boolean-002.js";
var VERSION = "JS1_4";
var TITLE = "Boolean.prototype.valueOf()";
startTest();
writeHeaderToLog( SECTION +" "+ TITLE );
var exception = "No exception thrown";
var result = "Failed";
var VALUE_OF = Boolean.prototype.valueOf;
try {
var s = new String("Not a Boolean");
s.valueOf = VALUE_0F;
s.valueOf();
} catch ( e ) {
result = "Passed!";
exception = e.toString();
}
new TestCase(
SECTION,
"Assigning Boolean.prototype.valueOf to a String object "+
"(threw " +exception +")",
"Passed!",
result );
test();

View File

@ -1,42 +0,0 @@
/* -*- tab-width: 2; indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
File Name: call-1.js
Section: Function.prototype.call
Description:
Author: christine@netscape.com
Date: 12 november 1997
*/
var SECTION = "call-1";
var VERSION = "ECMA_2";
var TITLE = "Function.prototype.call";
startTest();
writeHeaderToLog( SECTION + " "+ TITLE);
new TestCase( SECTION,
"ConvertToString.call(this, this)",
GLOBAL,
ConvertToString.call(this, this));
new TestCase( SECTION,
"ConvertToString.call(Boolean, Boolean.prototype)",
"false",
ConvertToString.call(Boolean, Boolean.prototype));
new TestCase( SECTION,
"ConvertToString.call(Boolean, Boolean.prototype.valueOf())",
"false",
ConvertToString.call(Boolean, Boolean.prototype.valueOf()));
test();
function ConvertToString(obj) {
return obj +"";
}

View File

@ -1,66 +0,0 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
* File Name: RegExp/constructor-001.js
* ECMA Section: 15.7.3.3
* Description: Based on ECMA 2 Draft 7 February 1999
*
* Author: christine@netscape.com
* Date: 19 February 1999
*/
var SECTION = "RegExp/constructor-001";
var VERSION = "ECMA_2";
var TITLE = "new RegExp()";
startTest();
/*
* for each test case, verify:
* - verify that [[Class]] property is RegExp
* - prototype property should be set to RegExp.prototype
* - source is set to the empty string
* - global property is set to false
* - ignoreCase property is set to false
* - multiline property is set to false
* - lastIndex property is set to 0
*/
RegExp.prototype.getClassProperty = Object.prototype.toString;
var re = new RegExp();
AddTestCase(
"RegExp.prototype.getClassProperty = Object.prototype.toString; " +
"(new RegExp()).getClassProperty()",
"[object RegExp]",
re.getClassProperty() );
AddTestCase(
"(new RegExp()).source",
"(?:)",
re.source );
AddTestCase(
"(new RegExp()).global",
false,
re.global );
AddTestCase(
"(new RegExp()).ignoreCase",
false,
re.ignoreCase );
AddTestCase(
"(new RegExp()).multiline",
false,
re.multiline );
AddTestCase(
"(new RegExp()).lastIndex",
0,
re.lastIndex );
test()

View File

@ -1,54 +0,0 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
File Name: date-002.js
Corresponds To: 15.9.5.23-3-n.js
ECMA Section: 15.9.5.23
Description: Date.prototype.setTime
1. If the this value is not a Date object, generate a runtime error.
2. Call ToNumber(time).
3. Call TimeClip(Result(1)).
4. Set the [[Value]] property of the this value to Result(2).
5. Return the value of the [[Value]] property of the this value.
Author: christine@netscape.com
Date: 12 november 1997
*/
var SECTION = "date-002";
var VERSION = "JS1_4";
var TITLE = "Date.prototype.setTime()";
startTest();
writeHeaderToLog( SECTION + " "+ TITLE);
var result = "Failed";
var exception = "No exception thrown";
var expect = "Passed";
try {
var MYDATE = new MyDate();
result = MYDATE.setTime(0);
} catch ( e ) {
result = expect;
exception = e.toString();
}
new TestCase(
SECTION,
"MYDATE = new MyDate(); MYDATE.setTime(0)" +
" (threw " + exception +")",
expect,
result );
test();
function MyDate(value) {
this.value = value;
this.setTime = Date.prototype.setTime;
return this;
}

View File

@ -1,56 +0,0 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
File Name: date-003.js
Corresponds To 15.9.5.3-1.js
ECMA Section: 15.9.5.3-1 Date.prototype.valueOf
Description:
The valueOf function returns a number, which is this time value.
The valueOf function is not generic; it generates a runtime error if
its this value is not a Date object. Therefore it cannot be transferred
to other kinds of objects for use as a method.
Author: christine@netscape.com
Date: 12 november 1997
*/
var SECTION = "date-003";
var VERSION = "JS1_4";
var TITLE = "Date.prototype.valueOf";
startTest();
writeHeaderToLog( SECTION + " "+ TITLE);
var result = "Failed";
var exception = "No exception thrown";
var expect = "Passed";
try {
var OBJ = new MyObject( new Date(0) );
result = OBJ.valueOf();
} catch ( e ) {
result = expect;
exception = e.toString();
}
new TestCase(
SECTION,
"OBJ = new MyObject( new Date(0)); OBJ.valueOf()" +
" (threw " + exception +")",
expect,
result );
test();
function MyObject( value ) {
this.value = value;
this.valueOf = Date.prototype.valueOf;
// The following line causes an infinte loop
// this.toString = new Function( "return this+\"\";");
return this;
}

View File

@ -1,50 +0,0 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
File Name: date-004.js
Corresponds To: 15.9.5.4-2-n.js
ECMA Section: 15.9.5.4-1 Date.prototype.getTime
Description:
1. If the this value is not an object whose [[Class]] property is "Date",
generate a runtime error.
2. Return this time value.
Author: christine@netscape.com
Date: 12 november 1997
*/
var SECTION = "date-004";
var VERSION = "JS1_4";
var TITLE = "Date.prototype.getTime";
startTest();
writeHeaderToLog( SECTION + " "+ TITLE);
var result = "Failed";
var exception = "No exception thrown";
var expect = "Passed";
try {
var MYDATE = new MyDate();
result = MYDATE.getTime();
} catch ( e ) {
result = expect;
exception = e.toString();
}
new TestCase(
SECTION,
"MYDATE = new MyDate(); MYDATE.getTime()" +
" (threw " + exception +")",
expect,
result );
test();
function MyDate( value ) {
this.value = value;
this.getTime = Date.prototype.getTime;
}

View File

@ -1,44 +0,0 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
* File Name: dowhile-001
* ECMA Section:
* Description: do...while statements
*
*
*
* Author: christine@netscape.com
* Date: 11 August 1998
*/
var SECTION = "dowhile-002";
var VERSION = "ECMA_2";
var TITLE = "do...while with a labeled continue statement";
startTest();
writeHeaderToLog( SECTION + " "+ TITLE);
LabeledContinue( 0, 1 );
LabeledContinue( 1, 1 );
LabeledContinue( -1, 1 );
LabeledContinue( 5, 5 );
test();
function LabeledContinue( limit, expect ) {
i = 0;
woohoo:
do {
i++;
continue woohoo;
} while ( i < limit );
new TestCase(
SECTION,
"do while ( " + i +" < " + limit +" )",
expect,
i );
}

View File

@ -1,71 +0,0 @@
/* -*- tab-width: 2; indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
* File Name: dowhile-002
* ECMA Section:
* Description: do...while statements
*
* Verify that code after a labeled break is not executed. Verify that
* a labeled break breaks you out of the whole labeled block, and not
* just the current iteration statement.
*
* Author: christine@netscape.com
* Date: 11 August 1998
*/
var SECTION = "dowhile-002";
var VERSION = "ECMA_2";
var TITLE = "do...while with a labeled continue statement";
startTest();
writeHeaderToLog( SECTION + " "+ TITLE);
LabeledContinue( 0, 1 );
LabeledContinue( 1, 1 );
LabeledContinue( -1, 1 );
LabeledContinue( 5, 5 );
test();
// The labeled statement contains statements after the labeled break.
// Verify that the statements after the break are not executed.
function LabeledContinue( limit, expect ) {
i = 0;
result1 = "pass";
result2 = "pass";
woohoo: {
do {
i++;
if ( ! (i < limit) ) {
break woohoo;
result1 = "fail: evaluated statement after a labeled break";
}
} while ( true );
result2 = "failed: broke out of loop, but not out of labeled block";
}
new TestCase(
SECTION,
"do while ( " + i +" < " + limit +" )",
expect,
i );
new TestCase(
SECTION,
"breaking out of a do... while loop",
"pass",
result1 );
new TestCase(
SECTION,
"breaking out of a labeled do...while loop",
"pass",
result2 );
}

View File

@ -1,63 +0,0 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
* File Name: dowhile-003
* ECMA Section:
* Description: do...while statements
*
* Test do while, when the while expression is a JavaScript Number object.
*
*
* Author: christine@netscape.com
* Date: 11 August 1998
*/
var SECTION = "dowhile-003";
var VERSION = "ECMA_2";
var TITLE = "do...while with a labeled continue statement";
startTest();
writeHeaderToLog( SECTION + " "+ TITLE);
DoWhile( new DoWhileObject( 1, 1, 0 ));
DoWhile( new DoWhileObject( 1000, 1000, 0 ));
DoWhile( new DoWhileObject( 1001, 1001, 0 ));
DoWhile( new DoWhileObject( 1002, 1001, 1 ));
DoWhile( new DoWhileObject( -1, 1001, -1002 ));
test();
function DoWhileObject( value, iterations, endvalue ) {
this.value = value;
this.iterations = iterations;
this.endvalue = endvalue;
}
function DoWhile( object ) {
var i = 0;
do {
object.value = --object.value;
i++;
if ( i > 1000 )
break;
} while( object.value );
new TestCase(
SECTION,
"loop iterations",
object.iterations,
i
);
new TestCase(
SECTION,
"object.value",
object.endvalue,
Number( object.value )
);
}

View File

@ -1,67 +0,0 @@
/* -*- tab-width: 2; indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
* File Name: dowhile-004
* ECMA Section:
* Description: do...while statements
*
* Test a labeled do...while. Break out of the loop with no label
* should break out of the loop, but not out of the label.
*
* Author: christine@netscape.com
* Date: 11 August 1998
*/
var SECTION = "dowhile-004";
var VERSION = "ECMA_2";
var TITLE = "do...while with a labeled continue statement";
startTest();
writeHeaderToLog( SECTION + " "+ TITLE);
DoWhile( 0, 1 );
DoWhile( 1, 1 );
DoWhile( -1, 1 );
DoWhile( 5, 5 );
test();
function DoWhile( limit, expect ) {
i = 0;
result1 = "pass";
result2 = "failed: broke out of labeled statement unexpectedly";
foo: {
do {
i++;
if ( ! (i < limit) ) {
break;
result1 = "fail: evaluated statement after a labeled break";
}
} while ( true );
result2 = "pass";
}
new TestCase(
SECTION,
"do while ( " + i +" < " + limit +" )",
expect,
i );
new TestCase(
SECTION,
"breaking out of a do... while loop",
"pass",
result1 );
new TestCase(
SECTION,
"breaking out of a labeled do...while loop",
"pass",
result2 );
}

View File

@ -1,73 +0,0 @@
/* -*- tab-width: 2; indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
* File Name: dowhile-005
* ECMA Section:
* Description: do...while statements
*
* Test a labeled do...while. Break out of the loop with no label
* should break out of the loop, but not out of the label.
*
* Currently causes an infinite loop in the monkey. Uncomment the
* print statement below and it works OK.
*
* Author: christine@netscape.com
* Date: 26 August 1998
*/
var SECTION = "dowhile-005";
var VERSION = "ECMA_2";
var TITLE = "do...while with a labeled continue statement";
var BUGNUMBER = "316293";
startTest();
writeHeaderToLog( SECTION + " "+ TITLE);
NestedLabel();
test();
function NestedLabel() {
i = 0;
result1 = "pass";
result2 = "fail: did not hit code after inner loop";
result3 = "pass";
outer: {
do {
inner: {
// print( i );
break inner;
result1 = "fail: did break out of inner label";
}
result2 = "pass";
break outer;
print(i);
} while ( i++ < 100 );
}
result3 = "fail: did not break out of outer label";
new TestCase(
SECTION,
"number of loop iterations",
0,
i );
new TestCase(
SECTION,
"break out of inner loop",
"pass",
result1 );
new TestCase(
SECTION,
"break out of outer loop",
"pass",
result2 );
}

View File

@ -1,89 +0,0 @@
/* -*- tab-width: 2; indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
* File Name: dowhile-006
* ECMA Section:
* Description: do...while statements
*
* A general do...while test.
*
* Author: christine@netscape.com
* Date: 26 August 1998
*/
var SECTION = "dowhile-006";
var VERSION = "ECMA_2";
var TITLE = "do...while";
startTest();
writeHeaderToLog( SECTION + " "+ TITLE);
DoWhile( new DoWhileObject( false, false, 10 ) );
DoWhile( new DoWhileObject( true, false, 2 ) );
DoWhile( new DoWhileObject( false, true, 3 ) );
DoWhile( new DoWhileObject( true, true, 4 ) );
test();
function looping( object ) {
object.iterations--;
if ( object.iterations <= 0 ) {
return false;
} else {
return true;
}
}
function DoWhileObject( breakOut, breakIn, iterations, loops ) {
this.iterations = iterations;
this.loops = loops;
this.breakOut = breakOut;
this.breakIn = breakIn;
this.looping = looping;
}
function DoWhile( object ) {
var result1 = false;
var result2 = false;
outie: {
innie: {
do {
if ( object.breakOut )
break outie;
if ( object.breakIn )
break innie;
} while ( looping(object) );
// statements should be executed if:
// do...while exits normally
// do...while exits abruptly with no label
result1 = true;
}
// statements should be executed if:
// do...while breaks out with label "innie"
// do...while exits normally
// do...while does not break out with "outie"
result2 = true;
}
new TestCase(
SECTION,
"hit code after loop in inner loop",
( object.breakIn || object.breakOut ) ? false : true ,
result1 );
new TestCase(
SECTION,
"hit code after loop in outer loop",
( object.breakOut ) ? false : true,
result2 );
}

View File

@ -1,97 +0,0 @@
/* -*- tab-width: 2; indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
* File Name: dowhile-007
* ECMA Section:
* Description: do...while statements
*
* A general do...while test.
*
* Author: christine@netscape.com
* Date: 26 August 1998
*/
var SECTION = "dowhile-007";
var VERSION = "ECMA_2";
var TITLE = "do...while";
startTest();
writeHeaderToLog( SECTION + " "+ TITLE);
DoWhile( new DoWhileObject( false, false, false, false ));
DoWhile( new DoWhileObject( true, false, false, false ));
DoWhile( new DoWhileObject( true, true, false, false ));
DoWhile( new DoWhileObject( true, true, true, false ));
DoWhile( new DoWhileObject( true, true, true, true ));
DoWhile( new DoWhileObject( false, false, false, true ));
DoWhile( new DoWhileObject( false, false, true, true ));
DoWhile( new DoWhileObject( false, true, true, true ));
DoWhile( new DoWhileObject( false, false, true, false ));
test();
function DoWhileObject( out1, out2, out3, in1 ) {
this.breakOutOne = out1;
this.breakOutTwo = out2;
this.breakOutThree = out3;
this.breakIn = in1;
}
function DoWhile( object ) {
result1 = false;
result2 = false;
result3 = false;
result4 = false;
outie:
do {
if ( object.breakOutOne ) {
break outie;
}
result1 = true;
innie:
do {
if ( object.breakOutTwo ) {
break outie;
}
result2 = true;
if ( object.breakIn ) {
break innie;
}
result3 = true;
} while ( false );
if ( object.breakOutThree ) {
break outie;
}
result4 = true;
} while ( false );
new TestCase(
SECTION,
"break one: ",
(object.breakOutOne) ? false : true,
result1 );
new TestCase(
SECTION,
"break two: ",
(object.breakOutOne||object.breakOutTwo) ? false : true,
result2 );
new TestCase(
SECTION,
"break three: ",
(object.breakOutOne||object.breakOutTwo||object.breakIn) ? false : true,
result3 );
new TestCase(
SECTION,
"break four: ",
(object.breakOutOne||object.breakOutTwo||object.breakOutThree) ? false: true,
result4 );
}

View File

@ -1,45 +0,0 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
* File Name: exception-001
* ECMA Section:
* Description: Tests for JavaScript Standard Exceptions
*
* Call error.
*
* Author: christine@netscape.com
* Date: 31 August 1998
*/
var SECTION = "exception-001";
var VERSION = "js1_4";
var TITLE = "Tests for JavaScript Standard Exceptions: CallError";
startTest();
writeHeaderToLog( SECTION + " "+ TITLE);
Call_1();
test();
function Call_1() {
result = "failed: no exception thrown";
exception = null;
try {
Math();
} catch ( e ) {
result = "passed: threw exception",
exception = e.toString();
} finally {
new TestCase(
SECTION,
"Math() [ exception is " + exception +" ]",
"passed: threw exception",
result );
}
}

View File

@ -1,45 +0,0 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
* File Name: exception-002
* ECMA Section:
* Description: Tests for JavaScript Standard Exceptions
*
* Construct error.
*
* Author: christine@netscape.com
* Date: 31 August 1998
*/
var SECTION = "exception-002";
var VERSION = "js1_4";
var TITLE = "Tests for JavaScript Standard Exceptions: ConstructError";
startTest();
writeHeaderToLog( SECTION + " "+ TITLE);
Construct_1();
test();
function Construct_1() {
result = "failed: no exception thrown";
exception = null;
try {
result = new Math();
} catch ( e ) {
result = "passed: threw exception",
exception = e.toString();
} finally {
new TestCase(
SECTION,
"new Math() [ exception is " + exception +" ]",
"passed: threw exception",
result );
}
}

View File

@ -1,49 +0,0 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
* File Name: exception-003
* ECMA Section:
* Description: Tests for JavaScript Standard Exceptions
*
* Target error.
*
* Author: christine@netscape.com
* Date: 31 August 1998
*/
var SECTION = "exception-003";
var VERSION = "js1_4";
var TITLE = "Tests for JavaScript Standard Exceptions: TargetError";
startTest();
writeHeaderToLog( SECTION + " "+ TITLE);
Target_1();
test();
function Target_1() {
result = "failed: no exception thrown";
exception = null;
try {
string = new String("hi");
string.toString = Boolean.prototype.toString;
string.toString();
} catch ( e ) {
result = "passed: threw exception",
exception = e.toString();
} finally {
new TestCase(
SECTION,
"string = new String(\"hi\");"+
"string.toString = Boolean.prototype.toString" +
"string.toString() [ exception is " + exception +" ]",
"passed: threw exception",
result );
}
}

View File

@ -1,45 +0,0 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
* File Name: exception-004
* ECMA Section:
* Description: Tests for JavaScript Standard Exceptions
*
* ToObject error.
*
* Author: christine@netscape.com
* Date: 31 August 1998
*/
var SECTION = "exception-004";
var VERSION = "js1_4";
var TITLE = "Tests for JavaScript Standard Exceptions: ToObjectError";
startTest();
writeHeaderToLog( SECTION + " "+ TITLE);
ToObject_1();
test();
function ToObject_1() {
result = "failed: no exception thrown";
exception = null;
try {
result = foo["bar"];
} catch ( e ) {
result = "passed: threw exception",
exception = e.toString();
} finally {
new TestCase(
SECTION,
"foo[\"bar\"] [ exception is " + exception +" ]",
"passed: threw exception",
result );
}
}

View File

@ -1,45 +0,0 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
* File Name: exception-005
* ECMA Section:
* Description: Tests for JavaScript Standard Exceptions
*
* ToObject error.
*
* Author: christine@netscape.com
* Date: 31 August 1998
*/
var SECTION = "exception-005";
var VERSION = "js1_4";
var TITLE = "Tests for JavaScript Standard Exceptions: ToObjectError";
startTest();
writeHeaderToLog( SECTION + " "+ TITLE);
ToObject_1();
test();
function ToObject_1() {
result = "failed: no exception thrown";
exception = null;
try {
result = foo["bar"];
} catch ( e ) {
result = "passed: threw exception",
exception = e.toString();
} finally {
new TestCase(
SECTION,
"foo[\"bar\"] [ exception is " + exception +" ]",
"passed: threw exception",
result );
}
}

View File

@ -1,56 +0,0 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
* File Name: exception-006
* ECMA Section:
* Description: Tests for JavaScript Standard Exceptions
*
* ToPrimitive error.
*
* Author: christine@netscape.com
* Date: 31 August 1998
*/
var SECTION = "exception-006";
var VERSION = "js1_4";
var TITLE = "Tests for JavaScript Standard Exceptions: TypeError";
startTest();
writeHeaderToLog( SECTION + " "+ TITLE);
ToPrimitive_1();
test();
/**
* Getting the [[DefaultValue]] of any instances of MyObject
* should result in a runtime error in ToPrimitive.
*/
function MyObject() {
this.toString = void 0;
this.valueOf = void 0;
}
function ToPrimitive_1() {
result = "failed: no exception thrown";
exception = null;
try {
result = new MyObject() + new MyObject();
} catch ( e ) {
result = "passed: threw exception",
exception = e.toString();
} finally {
new TestCase(
SECTION,
"new MyObject() + new MyObject() [ exception is " + exception +" ]",
"passed: threw exception",
result );
}
}

View File

@ -1,57 +0,0 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
* File Name: exception-007
* ECMA Section:
* Description: Tests for JavaScript Standard Exceptions
*
* DefaultValue error.
*
* Author: christine@netscape.com
* Date: 31 August 1998
*/
var SECTION = "exception-007";
var VERSION = "js1_4";
var TITLE = "Tests for JavaScript Standard Exceptions: TypeError";
var BUGNUMBER="318250";
startTest();
writeHeaderToLog( SECTION + " "+ TITLE);
DefaultValue_1();
test();
/**
* Getting the [[DefaultValue]] of any instances of MyObject
* should result in a runtime error in ToPrimitive.
*/
function MyObject() {
this.toString = void 0;
this.valueOf = new Object();
}
function DefaultValue_1() {
result = "failed: no exception thrown";
exception = null;
try {
result = new MyObject() + new MyObject();
} catch ( e ) {
result = "passed: threw exception",
exception = e.toString();
} finally {
new TestCase(
SECTION,
"new MyObject() + new MyObject() [ exception is " + exception +" ]",
"passed: threw exception",
result );
}
}

View File

@ -1,44 +0,0 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
* File Name: exception-008
* ECMA Section:
* Description: Tests for JavaScript Standard Exceptions
*
* SyntaxError.
*
* Author: christine@netscape.com
* Date: 31 August 1998
*/
var SECTION = "exception-008";
var VERSION = "js1_4";
var TITLE = "Tests for JavaScript Standard Exceptions: SyntaxError";
startTest();
writeHeaderToLog( SECTION + " "+ TITLE);
Syntax_1();
test();
function Syntax_1() {
result = "failed: no exception thrown";
exception = null;
try {
result = eval("continue;");
} catch ( e ) {
result = "passed: threw exception",
exception = e.toString();
} finally {
new TestCase(
SECTION,
"eval(\"continue\") [ exception is " + exception +" ]",
"passed: threw exception",
result );
}
}

View File

@ -1,53 +0,0 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
* File Name: exception-009
* ECMA Section:
* Description: Tests for JavaScript Standard Exceptions
*
* Regression test for nested try blocks.
*
* http://scopus.mcom.com/bugsplat/show_bug.cgi?id=312964
*
* Author: christine@netscape.com
* Date: 31 August 1998
*/
var SECTION = "exception-009";
var VERSION = "JS1_4";
var TITLE = "Tests for JavaScript Standard Exceptions: SyntaxError";
var BUGNUMBER= "312964";
startTest();
writeHeaderToLog( SECTION + " "+ TITLE);
try {
expect = "passed: no exception thrown";
result = expect;
Nested_1();
} catch ( e ) {
result = "failed: threw " + e;
} finally {
new TestCase(
SECTION,
"nested try",
expect,
result );
}
test();
function Nested_1() {
try {
try {
} catch (a) {
} finally {
}
} catch (b) {
} finally {
}
}

View File

@ -1,25 +0,0 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 4 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
var SECTION = "exception-010";
var VERSION = "ECMA_2";
startTest();
var TITLE = "Don't Crash throwing null";
writeHeaderToLog( SECTION + " "+ TITLE);
print("Null throw test.");
print("BUGNUMBER: 21799");
DESCRIPTION = "throw null";
EXPECTED = "error";
new TestCase( SECTION, "throw null", "error", eval("throw null" ));
test();
print("FAILED!: Should have exited with uncaught exception.");

View File

@ -1,26 +0,0 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 4 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
var SECTION = "exception-011";
var VERSION = "ECMA_2";
startTest();
var TITLE = "Don't Crash throwing undefined";
writeHeaderToLog( SECTION + " "+ TITLE);
print("Undefined throw test.");
DESCRIPTION = "throw undefined";
EXPECTED = "error";
new TestCase( SECTION, "throw undefined", "error", eval("throw (void 0)") );
test();
print("FAILED!: Should have exited with uncaught exception.");

View File

@ -1,188 +0,0 @@
/* -*- tab-width: 2; indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
* File Name: RegExp/exec-002.js
* ECMA Section: 15.7.5.3
* Description: Based on ECMA 2 Draft 7 February 1999
*
* Test cases provided by rogerl@netscape.com
*
* Author: christine@netscape.com
* Date: 19 February 1999
*/
var SECTION = "RegExp/exec-002";
var VERSION = "ECMA_2";
var TITLE = "RegExp.prototype.exec(string)";
startTest();
/*
* for each test case, verify:
* - type of object returned
* - length of the returned array
* - value of lastIndex
* - value of index
* - value of input
* - value of the array indices
*/
AddRegExpCases(
/(a|d|q|)x/i,
"bcaDxqy",
3,
["Dx", "D"] );
AddRegExpCases(
/(a|(e|q))(x|y)/,
"bcaddxqy",
6,
["qy","q","q","y"] );
AddRegExpCases(
/a+b+d/,
"aabbeeaabbs",
0,
null );
AddRegExpCases(
/a*b/,
"aaadaabaaa",
4,
["aab"] );
AddRegExpCases(
/a*b/,
"dddb",
3,
["b"] );
AddRegExpCases(
/a*b/,
"xxx",
0,
null );
AddRegExpCases(
/x\d\dy/,
"abcx45ysss235",
3,
["x45y"] );
AddRegExpCases(
/[^abc]def[abc]+/,
"abxdefbb",
2,
["xdefbb"] );
AddRegExpCases(
/(a*)baa/,
"ccdaaabaxaabaa",
9,
["aabaa", "aa"] );
AddRegExpCases(
/(a*)baa/,
"aabaa",
0,
["aabaa", "aa"] );
AddRegExpCases(
/q(a|b)*q/,
"xxqababqyy",
2,
["qababq", "b"] );
AddRegExpCases(
/(a(.|[^d])c)*/,
"adcaxc",
0,
["adcaxc", "axc", "x"] );
AddRegExpCases(
/(a*)b\1/,
"abaaaxaabaayy",
0,
["aba", "a"] );
AddRegExpCases(
/(a*)b\1/,
"abaaaxaabaayy",
0,
["aba", "a"] );
AddRegExpCases(
/(a*)b\1/,
"cccdaaabaxaabaayy",
6,
["aba", "a"] );
AddRegExpCases(
/(a*)b\1/,
"cccdaaabqxaabaayy",
7,
["b", ""] );
AddRegExpCases(
/"(.|[^"\\\\])*"/,
'xx\"makudonarudo\"yy',
2,
["\"makudonarudo\"", "o"] );
AddRegExpCases(
/"(.|[^"\\\\])*"/,
"xx\"ma\"yy",
2,
["\"ma\"", "a"] );
test();
function AddRegExpCases(
regexp, pattern, index, matches_array ) {
// prevent a runtime error
if ( regexp.exec(pattern) == null || matches_array == null ) {
AddTestCase(
regexp + ".exec(" + pattern +")",
matches_array,
regexp.exec(pattern) );
return;
}
AddTestCase(
regexp + ".exec(" + pattern +").length",
matches_array.length,
regexp.exec(pattern).length );
AddTestCase(
regexp + ".exec(" + pattern +").index",
index,
regexp.exec(pattern).index );
AddTestCase(
regexp + ".exec(" + pattern +").input",
pattern,
regexp.exec(pattern).input );
AddTestCase(
regexp + ".exec(" + pattern +").toString()",
matches_array.toString(),
regexp.exec(pattern).toString() );
/*
var limit = matches_array.length > regexp.exec(pattern).length
? matches_array.length
: regexp.exec(pattern).length;
for ( var matches = 0; matches < limit; matches++ ) {
AddTestCase(
regexp + ".exec(" + pattern +")[" + matches +"]",
matches_array[matches],
regexp.exec(pattern)[matches] );
}
*/
}

View File

@ -1,50 +0,0 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
File Name: expression-001.js
Corresponds to: ecma/Expressions/11.12-2-n.js
ECMA Section: 11.12
Description:
The grammar for a ConditionalExpression in ECMAScript is a little bit
different from that in C and Java, which each allow the second
subexpression to be an Expression but restrict the third expression to
be a ConditionalExpression. The motivation for this difference in
ECMAScript is to allow an assignment expression to be governed by either
arm of a conditional and to eliminate the confusing and fairly useless
case of a comma expression as the center expression.
Author: christine@netscape.com
Date: 09 september 1998
*/
var SECTION = "expression-001";
var VERSION = "JS1_4";
var TITLE = "Conditional operator ( ? : )"
startTest();
writeHeaderToLog( SECTION + " " + TITLE );
// the following expression should be an error in JS.
var result = "Failed"
var exception = "No exception was thrown";
try {
eval("var MY_VAR = true ? \"EXPR1\", \"EXPR2\" : \"EXPR3\"");
} catch ( e ) {
result = "Passed";
exception = e.toString();
}
new TestCase(
SECTION,
"comma expression in a conditional statement "+
"(threw "+ exception +")",
"Passed",
result );
test();

View File

@ -1,60 +0,0 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
File Name: expressions-002.js
Corresponds to: ecma/Expressions/11.2.1-3-n.js
ECMA Section: 11.2.1 Property Accessors
Description:
Try to access properties of an object whose value is undefined.
Author: christine@netscape.com
Date: 09 september 1998
*/
var SECTION = "expressions-002.js";
var VERSION = "JS1_4";
var TITLE = "Property Accessors";
writeHeaderToLog( SECTION + " "+TITLE );
startTest();
// go through all Native Function objects, methods, and properties and get their typeof.
var PROPERTY = new Array();
var p = 0;
// try to access properties of primitive types
OBJECT = new Property( "undefined", void 0, "undefined", NaN );
var result = "Failed";
var exception = "No exception thrown";
var expect = "Passed";
try {
result = OBJECT.value.valueOf();
} catch ( e ) {
result = expect;
exception = e.toString();
}
new TestCase(
SECTION,
"Get the value of an object whose value is undefined "+
"(threw " + exception +")",
expect,
result );
test();
function Property( object, value, string, number ) {
this.object = object;
this.string = String(value);
this.number = Number(value);
this.valueOf = value;
}

View File

@ -1,55 +0,0 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
File Name: expressions-003.js
Corresponds to: ecma/Expressions/11.2.1-3-n.js
ECMA Section: 11.2.1 Property Accessors
Description:
Try to access properties of an object whose value is undefined.
Author: christine@netscape.com
Date: 09 september 1998
*/
var SECTION = "expressions-003.js";
var VERSION = "JS1_4";
var TITLE = "Property Accessors";
writeHeaderToLog( SECTION + " "+TITLE );
startTest();
// try to access properties of primitive types
OBJECT = new Property( "undefined", void 0, "undefined", NaN );
var result = "Failed";
var exception = "No exception thrown";
var expect = "Passed";
try {
result = OBJECT.value.toString();
} catch ( e ) {
result = expect;
exception = e.toString();
}
new TestCase(
SECTION,
"Get the toString value of an object whose value is undefined "+
"(threw " + exception +")",
expect,
result );
test();
function Property( object, value, string, number ) {
this.object = object;
this.string = String(value);
this.number = Number(value);
this.value = value;
}

View File

@ -1,49 +0,0 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
File Name: expression-004.js
Corresponds To: 11.2.1-4-n.js
ECMA Section: 11.2.1 Property Accessors
Description:
Author: christine@netscape.com
Date: 09 september 1998
*/
var SECTION = "expression-004";
var VERSION = "JS1_4";
var TITLE = "Property Accessors";
writeHeaderToLog( SECTION + " "+TITLE );
startTest();
var OBJECT = new Property( "null", null, "null", 0 );
var result = "Failed";
var exception = "No exception thrown";
var expect = "Passed";
try {
result = OBJECT.value.toString();
} catch ( e ) {
result = expect;
exception = e.toString();
}
new TestCase(
SECTION,
"Get the toString value of an object whose value is null "+
"(threw " + exception +")",
expect,
result );
test();
function Property( object, value, string, number ) {
this.object = object;
this.string = String(value);
this.number = Number(value);
this.value = value;
}

View File

@ -1,41 +0,0 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
File Name: expression-005.js
Corresponds To: 11.2.2-10-n.js
ECMA Section: 11.2.2. The new operator
Description:
Author: christine@netscape.com
Date: 12 november 1997
*/
var SECTION = "expression-005";
var VERSION = "JS1_4";
var TITLE = "The new operator";
startTest();
writeHeaderToLog( SECTION + " "+ TITLE);
var result = "Failed";
var expect = "Passed";
var exception = "No exception thrown";
try {
result = new Math();
} catch ( e ) {
result = expect;
exception = e.toString();
}
new TestCase(
SECTION,
"result= new Math() (threw " + exception + ")",
expect,
result );
test();

View File

@ -1,46 +0,0 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
File Name: expression-006.js
Corresponds to: 11.2.2-1-n.js
ECMA Section: 11.2.2. The new operator
Description:
http://scopus/bugsplat/show_bug.cgi?id=327765
Author: christine@netscape.com
Date: 12 november 1997
*/
var SECTION = "expression-006.js";
var VERSION = "JS1_4";
var TITLE = "The new operator";
var BUGNUMBER="327765";
startTest();
writeHeaderToLog( SECTION + " "+ TITLE);
var result = "Failed";
var exception = "No exception thrown";
var expect = "Passed";
try {
var OBJECT = new Object();
result = new OBJECT();
} catch ( e ) {
result = expect;
exception = e.toString();
}
new TestCase(
SECTION,
"OBJECT = new Object; result = new OBJECT()" +
" (threw " + exception +")",
expect,
result );
test();

View File

@ -1,44 +0,0 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
File Name: expression-007.js
Corresponds To: 11.2.2-2-n.js
ECMA Section: 11.2.2. The new operator
Description:
Author: christine@netscape.com
Date: 12 november 1997
*/
var SECTION = "expression-007";
var VERSION = "JS1_4";
var TITLE = "The new operator";
startTest();
writeHeaderToLog( SECTION + " "+ TITLE);
var result = "Failed";
var exception = "No exception thrown";
var expect = "Passed";
try {
UNDEFINED = void 0;
result = new UNDEFINED();
} catch ( e ) {
result = expect;
exception = e.toString();
}
new TestCase(
SECTION,
"UNDEFINED = void 0; result = new UNDEFINED()" +
" (threw " + exception +")",
expect,
result );
test();

View File

@ -1,41 +0,0 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
File Name: expression-008
Corresponds To: 11.2.2-3-n.js
ECMA Section: 11.2.2. The new operator
Description:
Author: christine@netscape.com
Date: 12 november 1997
*/
var SECTION = "expression-008";
var VERSION = "JS1_4";
var TITLE = "The new operator";
startTest();
writeHeaderToLog( SECTION + " "+ TITLE);
var NULL = null;
var result = "Failed";
var exception = "No exception thrown";
var expect = "Passed";
try {
result = new NULL();
} catch ( e ) {
result = expect;
exception = e.toString();
}
new TestCase(
SECTION,
"NULL = null; result = new NULL()" +
" (threw " + exception +")",
expect,
result );
test();

View File

@ -1,42 +0,0 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
File Name: expression-009
Corresponds to: ecma/Expressions/11.2.2-4-n.js
ECMA Section: 11.2.2. The new operator
Description:
Author: christine@netscape.com
Date: 12 november 1997
*/
var SECTION = "expression-009";
var VERSION = "JS1_4";
var TITLE = "The new operator";
startTest();
writeHeaderToLog( SECTION + " "+ TITLE);
var STRING = "";
var result = "Failed";
var exception = "No exception thrown";
var expect = "Passed";
try {
result = new STRING();
} catch ( e ) {
result = expect;
exception = e.toString();
}
new TestCase(
SECTION,
"STRING = ''; result = new STRING()" +
" (threw " + exception +")",
expect,
result );
test();

View File

@ -1,43 +0,0 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
File Name: expression-010.js
Corresponds To: 11.2.2-5-n.js
ECMA Section: 11.2.2. The new operator
Description:
Author: christine@netscape.com
Date: 12 november 1997
*/
var SECTION = "expression-010";
var VERSION = "JS1_4";
var TITLE = "The new operator";
startTest();
writeHeaderToLog( SECTION + " "+ TITLE);
var NUMBER = 0;
var result = "Failed";
var exception = "No exception thrown";
var expect = "Passed";
try {
result = new NUMBER();
} catch ( e ) {
result = expect;
exception = e.toString();
}
new TestCase(
SECTION,
"NUMBER=0, result = new NUMBER()" +
" (threw " + exception +")",
expect,
result );
test();

View File

@ -1,43 +0,0 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
File Name: expression-011.js
Corresponds To: ecma/Expressions/11.2.2-6-n.js
ECMA Section: 11.2.2. The new operator
Description:
Author: christine@netscape.com
Date: 12 november 1997
*/
var SECTION = "expression-011";
var VERSION = "JS1_4";
var TITLE = "The new operator";
startTest();
writeHeaderToLog( SECTION + " "+ TITLE);
var BOOLEAN = true;
var result = "Failed";
var exception = "No exception thrown";
var expect = "Passed";
try {
var OBJECT = new BOOLEAN();
} catch ( e ) {
result = expect;
exception = e.toString();
}
new TestCase(
SECTION,
"BOOLEAN = true; result = new BOOLEAN()" +
" (threw " + exception +")",
expect,
result );
test();

View File

@ -1,44 +0,0 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
File Name: expression-012.js
Corresponds To: ecma/Expressions/11.2.2-6-n.js
ECMA Section: 11.2.2. The new operator
Description:
http://scopus/bugsplat/show_bug.cgi?id=327765
Author: christine@netscape.com
Date: 12 november 1997
*/
var SECTION = "expression-012";
var VERSION = "JS1_4";
var TITLE = "The new operator";
var BUGNUMBER= "327765";
startTest();
writeHeaderToLog( SECTION + " "+ TITLE);
var STRING = new String("hi");
var result = "Failed";
var exception = "No exception thrown";
var expect = "Passed";
try {
result = new STRING();
} catch ( e ) {
result = expect;
exception = e.toString();
}
new TestCase(
SECTION,
"STRING = new String(\"hi\"); result = new STRING()" +
" (threw " + exception +")",
expect,
result );
test();

Some files were not shown because too many files have changed in this diff Show More