__ b(ne, &shift_arguments);
// Do not transform the receiver for native (Compilerhints already in r3).
- __ tst(r3, Operand(1 << (SharedFunctionInfo::kES5Native +
- kSmiTagSize)));
+ __ tst(r3, Operand(1 << (SharedFunctionInfo::kNative + kSmiTagSize)));
__ b(ne, &shift_arguments);
// Compute the receiver in non-strict mode.
__ b(ne, &push_receiver);
// Do not transform the receiver for strict mode functions.
- __ tst(r2, Operand(1 << (SharedFunctionInfo::kES5Native +
- kSmiTagSize)));
+ __ tst(r2, Operand(1 << (SharedFunctionInfo::kNative + kSmiTagSize)));
__ b(ne, &push_receiver);
// Compute the receiver in non-strict mode.
}
#endif
- // Strict mode functions need to replace the receiver with undefined
- // when called as functions (without an explicit receiver
- // object). r5 is zero for method calls and non-zero for function
- // calls.
- if (info->is_strict_mode()) {
+ // Strict mode functions and builtins need to replace the receiver
+ // with undefined when called as functions (without an explicit
+ // receiver object). r5 is zero for method calls and non-zero for
+ // function calls.
+ if (info->is_strict_mode() || info->is_native()) {
Label ok;
__ cmp(r5, Operand(0));
__ b(eq, &ok);
// fp: Caller's frame pointer.
// lr: Caller's pc.
- // Strict mode functions need to replace the receiver with undefined
- // when called as functions (without an explicit receiver
- // object). r5 is zero for method calls and non-zero for function
- // calls.
- if (info_->is_strict_mode()) {
+ // Strict mode functions and builtins need to replace the receiver
+ // with undefined when called as functions (without an explicit
+ // receiver object). r5 is zero for method calls and non-zero for
+ // function calls.
+ if (info_->is_strict_mode() || info_->is_native()) {
Label ok;
__ cmp(r5, Operand(0));
__ b(eq, &ok);
info.MarkAsGlobal();
info.SetExtension(extension);
info.SetPreParseData(pre_data);
- if (natives == NATIVES_CODE) info.MarkAsAllowingNativesSyntax();
+ if (natives == NATIVES_CODE) {
+ info.MarkAsAllowingNativesSyntax();
+ info.MarkAsNative();
+ }
result = MakeFunctionInfo(&info);
if (extension == NULL && !result.is_null()) {
compilation_cache->PutScript(source, result);
info.SetFunction(literal);
info.SetScope(literal->scope());
if (literal->scope()->is_strict_mode()) info.MarkAsStrictMode();
+ if (script->type()->value() == Script::TYPE_NATIVE) info.MarkAsNative();
LiveEditFunctionTracker live_edit_tracker(info.isolate(), literal);
// Determine if the function can be lazily compiled. This is necessary to
bool allows_natives_syntax() const {
return IsNativesSyntaxAllowed::decode(flags_);
}
+ void MarkAsNative() {
+ flags_ |= IsNative::encode(true);
+ }
+ bool is_native() const {
+ return IsNative::decode(flags_);
+ }
void SetFunction(FunctionLiteral* literal) {
ASSERT(function_ == NULL);
function_ = literal;
void Initialize(Mode mode) {
mode_ = V8::UseCrankshaft() ? mode : NONOPT;
- if (!shared_info_.is_null() && shared_info_->strict_mode()) {
- MarkAsStrictMode();
+ if (!shared_info_.is_null()) {
+ if (shared_info_->strict_mode()) MarkAsStrictMode();
+ if (shared_info_->native()) MarkAsNative();
}
+
}
void SetMode(Mode mode) {
class IsStrictMode: public BitField<bool, 4, 1> {};
// Native syntax (%-stuff) allowed?
class IsNativesSyntaxAllowed: public BitField<bool, 5, 1> {};
+ // Is this a function from our natives.
+ class IsNative: public BitField<bool, 6, 1> {};
+
unsigned flags_;
-// Copyright 2009 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
share->set_num_literals(0);
share->set_end_position(0);
share->set_function_token_position(0);
- share->set_es5_native(false);
+ share->set_native(false);
return result;
}
inner->SetValueAt(i, push);
}
}
- // If the function we are inlining is a strict mode function, pass
- // undefined as the receiver for function calls (instead of the
- // global receiver).
- if (function->strict_mode() && call_kind == CALL_AS_FUNCTION) {
+ // If the function we are inlining is a strict mode function or a
+ // builtin function, pass undefined as the receiver for function
+ // calls (instead of the global receiver).
+ if ((target->shared()->native() || function->strict_mode()) &&
+ call_kind == CALL_AS_FUNCTION) {
inner->SetValueAt(0, undefined);
}
inner->SetValueAt(arity + 1, outer->LookupContext());
__ j(not_equal, &shift_arguments);
// Do not transform the receiver for natives (shared already in ebx).
- __ test_b(FieldOperand(ebx, SharedFunctionInfo::kES5NativeByteOffset),
- 1 << SharedFunctionInfo::kES5NativeBitWithinByte);
+ __ test_b(FieldOperand(ebx, SharedFunctionInfo::kNativeByteOffset),
+ 1 << SharedFunctionInfo::kNativeBitWithinByte);
__ j(not_equal, &shift_arguments);
// Compute the receiver in non-strict mode.
Factory* factory = masm->isolate()->factory();
// Do not transform the receiver for natives (shared already in ecx).
- __ test_b(FieldOperand(ecx, SharedFunctionInfo::kES5NativeByteOffset),
- 1 << SharedFunctionInfo::kES5NativeBitWithinByte);
+ __ test_b(FieldOperand(ecx, SharedFunctionInfo::kNativeByteOffset),
+ 1 << SharedFunctionInfo::kNativeBitWithinByte);
__ j(not_equal, &push_receiver);
// Compute the receiver in non-strict mode.
}
#endif
- // Strict mode functions need to replace the receiver with undefined
- // when called as functions (without an explicit receiver
- // object). ecx is zero for method calls and non-zero for function
- // calls.
- if (info->is_strict_mode()) {
+ // Strict mode functions and builtins need to replace the receiver
+ // with undefined when called as functions (without an explicit
+ // receiver object). ecx is zero for method calls and non-zero for
+ // function calls.
+ if (info->is_strict_mode() || info->is_native()) {
Label ok;
__ test(ecx, Operand(ecx));
__ j(zero, &ok, Label::kNear);
}
#endif
- // Strict mode functions need to replace the receiver with undefined
- // when called as functions (without an explicit receiver
- // object). ecx is zero for method calls and non-zero for function
- // calls.
- if (info_->is_strict_mode()) {
+ // Strict mode functions and builtins need to replace the receiver
+ // with undefined when called as functions (without an explicit
+ // receiver object). ecx is zero for method calls and non-zero for
+ // function calls.
+ if (info_->is_strict_mode() || info_->is_native()) {
Label ok;
__ test(ecx, Operand(ecx));
__ j(zero, &ok, Label::kNear);
__ Branch(&shift_arguments, ne, t0, Operand(zero_reg));
// Do not transform the receiver for native (Compilerhints already in a3).
- __ And(t0, a3, Operand(1 << (SharedFunctionInfo::kES5Native +
- kSmiTagSize)));
+ __ And(t0, a3, Operand(1 << (SharedFunctionInfo::kNative + kSmiTagSize)));
__ Branch(&shift_arguments, ne, t0, Operand(zero_reg));
// Compute the receiver in non-strict mode.
__ Branch(&push_receiver, ne, t0, Operand(zero_reg));
// Do not transform the receiver for native (Compilerhints already in a2).
- __ And(t0, a2, Operand(1 << (SharedFunctionInfo::kES5Native +
- kSmiTagSize)));
+ __ And(t0, a2, Operand(1 << (SharedFunctionInfo::kNative + kSmiTagSize)));
__ Branch(&push_receiver, ne, t0, Operand(zero_reg));
// Compute the receiver in non-strict mode.
}
-bool SharedFunctionInfo::es5_native() {
- return BooleanBit::get(compiler_hints(), kES5Native);
+bool SharedFunctionInfo::native() {
+ return BooleanBit::get(compiler_hints(), kNative);
}
-void SharedFunctionInfo::set_es5_native(bool value) {
+void SharedFunctionInfo::set_native(bool value) {
set_compiler_hints(BooleanBit::set(compiler_hints(),
- kES5Native,
+ kNative,
value));
}
inline bool strict_mode();
inline void set_strict_mode(bool value);
- // Indicates whether the function is a native ES5 function.
+ // Indicates whether the function is a native function.
// These needs special threatment in .call and .apply since
// null passed as the receiver should not be translated to the
// global object.
- inline bool es5_native();
- inline void set_es5_native(bool value);
+ inline bool native();
+ inline void set_native(bool value);
// Indicates whether or not the code in the shared function support
// deoptimization.
static const int kCodeAgeMask = 0x7;
static const int kOptimizationDisabled = 6;
static const int kStrictModeFunction = 7;
- static const int kES5Native = 8;
+ static const int kNative = 8;
private:
#if V8_HOST_ARCH_32_BIT
public:
// Constants for optimizing codegen for strict mode function and
- // es5 native tests.
+ // native tests.
// Allows to use byte-widgh instructions.
static const int kStrictModeBitWithinByte =
(kStrictModeFunction + kCompilerHintsSmiTagSize) % kBitsPerByte;
- static const int kES5NativeBitWithinByte =
- (kES5Native + kCompilerHintsSmiTagSize) % kBitsPerByte;
+ static const int kNativeBitWithinByte =
+ (kNative + kCompilerHintsSmiTagSize) % kBitsPerByte;
#if __BYTE_ORDER == __LITTLE_ENDIAN
static const int kStrictModeByteOffset = kCompilerHintsOffset +
(kStrictModeFunction + kCompilerHintsSmiTagSize) / kBitsPerByte;
- static const int kES5NativeByteOffset = kCompilerHintsOffset +
- (kES5Native + kCompilerHintsSmiTagSize) / kBitsPerByte;
+ static const int kNativeByteOffset = kCompilerHintsOffset +
+ (kNative + kCompilerHintsSmiTagSize) / kBitsPerByte;
#elif __BYTE_ORDER == __BIG_ENDIAN
static const int kStrictModeByteOffset = kCompilerHintsOffset +
(kCompilerHintsSize - 1) -
((kStrictModeFunction + kCompilerHintsSmiTagSize) / kBitsPerByte);
- static const int kES5NativeByteOffset = kCompilerHintsOffset +
+ static const int kNativeByteOffset = kCompilerHintsOffset +
(kCompilerHintsSize - 1) -
- ((kES5Native + kCompilerHintsSmiTagSize) / kBitsPerByte);
+ ((kNative + kCompilerHintsSmiTagSize) / kBitsPerByte);
#else
#error Unknown byte ordering
#endif
}
-// Set the ES5 native flag on the function.
+// Set the native flag on the function.
// This is used to decide if we should transform null and undefined
// into the global object when doing call and apply.
-RUNTIME_FUNCTION(MaybeObject*, Runtime_SetES5Flag) {
+RUNTIME_FUNCTION(MaybeObject*, Runtime_SetNativeFlag) {
NoHandleAllocation ha;
RUNTIME_ASSERT(args.length() == 1);
if (object->IsJSFunction()) {
JSFunction* func = JSFunction::cast(*object);
- func->shared()->set_es5_native(true);
+ func->shared()->set_native(true);
}
return isolate->heap()->undefined_value();
}
-// Copyright 2010 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
F(CompileForOnStackReplacement, 1, 1) \
F(SetNewFunctionAttributes, 1, 1) \
F(AllocateInNewSpace, 1, 1) \
- F(SetES5Flag, 1, 1) \
+ F(SetNativeFlag, 1, 1) \
\
/* Array join support */ \
F(PushIfAbsent, 2, 1) \
%FunctionSetName(f, key);
%FunctionRemovePrototype(f);
%SetProperty(object, key, f, attributes);
- %SetES5Flag(f);
+ %SetNativeFlag(f);
}
%ToFastProperties(object);
}
function GlobalEval(x) {
if (!IS_STRING(x)) return x;
+ var receiver = this;
var global_receiver = %GlobalReceiver(global);
- var this_is_global_receiver = (this === global_receiver);
+
+ if (receiver == null && !IS_UNDETECTABLE(receiver)) {
+ receiver = global_receiver;
+ }
+
+ var this_is_global_receiver = (receiver === global_receiver);
var global_is_detached = (global === global_receiver);
+ // For consistency with JSC we require the global object passed to
+ // eval to be the global object from which 'eval' originated. This
+ // is not mandated by the spec.
if (!this_is_global_receiver || global_is_detached) {
throw new $EvalError('The "this" object passed to eval must ' +
'be the global object from which eval originated');
var f = %CompileString(x);
if (!IS_FUNCTION(f)) return f;
- return %_CallFunction(this, f);
+ return %_CallFunction(receiver, f);
}
// Extensions for providing property getters and setters.
function ObjectDefineGetter(name, fun) {
- if (this == null && !IS_UNDETECTABLE(this)) {
- throw new $TypeError('Object.prototype.__defineGetter__: this is Null');
+ var receiver = this;
+ if (receiver == null && !IS_UNDETECTABLE(receiver)) {
+ receiver = %GlobalReceiver(global);
}
if (!IS_FUNCTION(fun)) {
throw new $TypeError('Object.prototype.__defineGetter__: Expecting function');
desc.setGet(fun);
desc.setEnumerable(true);
desc.setConfigurable(true);
- DefineOwnProperty(ToObject(this), ToString(name), desc, false);
+ DefineOwnProperty(ToObject(receiver), ToString(name), desc, false);
}
function ObjectLookupGetter(name) {
- if (this == null && !IS_UNDETECTABLE(this)) {
- throw new $TypeError('Object.prototype.__lookupGetter__: this is Null');
+ var receiver = this;
+ if (receiver == null && !IS_UNDETECTABLE(receiver)) {
+ receiver = %GlobalReceiver(global);
}
- return %LookupAccessor(ToObject(this), ToString(name), GETTER);
+ return %LookupAccessor(ToObject(receiver), ToString(name), GETTER);
}
function ObjectDefineSetter(name, fun) {
- if (this == null && !IS_UNDETECTABLE(this)) {
- throw new $TypeError('Object.prototype.__defineSetter__: this is Null');
+ var receiver = this;
+ if (receiver == null && !IS_UNDETECTABLE(receiver)) {
+ receiver = %GlobalReceiver(global);
}
if (!IS_FUNCTION(fun)) {
throw new $TypeError(
desc.setSet(fun);
desc.setEnumerable(true);
desc.setConfigurable(true);
- DefineOwnProperty(ToObject(this), ToString(name), desc, false);
+ DefineOwnProperty(ToObject(receiver), ToString(name), desc, false);
}
function ObjectLookupSetter(name) {
- if (this == null && !IS_UNDETECTABLE(this)) {
- throw new $TypeError('Object.prototype.__lookupSetter__: this is Null');
+ var receiver = this;
+ if (receiver == null && !IS_UNDETECTABLE(receiver)) {
+ receiver = %GlobalReceiver(global);
}
- return %LookupAccessor(ToObject(this), ToString(name), SETTER);
+ return %LookupAccessor(ToObject(receiver), ToString(name), SETTER);
}
// Do not transform the receiver for natives.
// SharedFunctionInfo is already loaded into rbx.
- __ testb(FieldOperand(rbx, SharedFunctionInfo::kES5NativeByteOffset),
- Immediate(1 << SharedFunctionInfo::kES5NativeBitWithinByte));
+ __ testb(FieldOperand(rbx, SharedFunctionInfo::kNativeByteOffset),
+ Immediate(1 << SharedFunctionInfo::kNativeBitWithinByte));
__ j(not_zero, &shift_arguments);
// Compute the receiver in non-strict mode.
__ j(not_equal, &push_receiver);
// Do not transform the receiver for natives.
- __ testb(FieldOperand(rdx, SharedFunctionInfo::kES5NativeByteOffset),
- Immediate(1 << SharedFunctionInfo::kES5NativeBitWithinByte));
+ __ testb(FieldOperand(rdx, SharedFunctionInfo::kNativeByteOffset),
+ Immediate(1 << SharedFunctionInfo::kNativeBitWithinByte));
__ j(not_zero, &push_receiver);
// Compute the receiver in non-strict mode.
}
#endif
- // Strict mode functions need to replace the receiver with undefined
- // when called as functions (without an explicit receiver
- // object). rcx is zero for method calls and non-zero for function
- // calls.
- if (info->is_strict_mode()) {
+ // Strict mode functions and builtins need to replace the receiver
+ // with undefined when called as functions (without an explicit
+ // receiver object). rcx is zero for method calls and non-zero for
+ // function calls.
+ if (info->is_strict_mode() || info->is_native()) {
Label ok;
__ testq(rcx, rcx);
__ j(zero, &ok, Label::kNear);
// when called as functions (without an explicit receiver
// object). rcx is zero for method calls and non-zero for function
// calls.
- if (info_->is_strict_mode()) {
+ if (info_->is_strict_mode() || info_->is_native()) {
Label ok;
__ testq(rcx, rcx);
__ j(zero, &ok, Label::kNear);
context->Global()->Set(v8_str("__proto__"), o);
Local<Value> value =
- Script::Compile(v8_str("propertyIsEnumerable(0)"))->Run();
+ Script::Compile(v8_str("this.propertyIsEnumerable(0)"))->Run();
CHECK(value->IsBoolean());
CHECK(!value->BooleanValue());
__proto__.__defineSetter__("a", function(v) { setter_value = v; });
eval("var a = 1");
assertEquals(1, setter_value);
-assertFalse(hasOwnProperty("a"));
+assertFalse(this.hasOwnProperty("a"));
eval("with({}) { eval('var a = 2') }");
assertEquals(2, setter_value);
-assertFalse(hasOwnProperty("a"));
+assertFalse(this.hasOwnProperty("a"));
// Function declarations are treated specially to match Safari. We do
// not call setters for them.
eval("function a() {}");
-assertTrue(hasOwnProperty("a"));
+assertTrue(this.hasOwnProperty("a"));
-__proto__.__defineSetter__("b", function(v) { assertUnreachable(); });
+__proto__.__defineSetter__("b", function(v) { assertUnreachable(); });
try {
eval("const b = 23");
assertUnreachable();
assertUnreachable();
} catch(e) {
assertEquals(42, e);
- assertFalse(hasOwnProperty("c"));
+ assertFalse(this.hasOwnProperty("c"));
}
-
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
assertEquals("[object global]", this.toString());
-assertEquals("[object global]", toString());
+assertEquals("[object Undefined]", toString());
assertEquals("[object global]", eval("this.toString()"));
-assertEquals("[object global]", eval("toString()"));
+assertEquals("[object Undefined]", eval("toString()"));
assertEquals("[object global]", eval("var f; this.toString()"));
-assertEquals("[object global]", eval("var f; toString()"));
+assertEquals("[object Undefined]", eval("var f; toString()"));
function F(f) {
assertEquals("[object global]", eval("var f; this.toString()"));
assertEquals("[object global]", eval("var f; toString()"));
- assertEquals("[object global]", eval("f()"));
+ assertEquals("[object Undefined]", eval("f()"));
// Receiver should be the arguments object here.
assertEquals("[object Arguments]", eval("arguments[0]()"));
--- /dev/null
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// See: http://code.google.com/p/v8/issues/detail?id=1365
+
+// Check that builtin methods are passed undefined as the receiver
+// when called as functions through variables.
+
+// Flags: --allow-natives-syntax
+
+// Global variable.
+var valueOf = Object.prototype.valueOf;
+var hasOwnProperty = Object.prototype.hasOwnProperty;
+
+function callGlobalValueOf() { valueOf(); }
+function callGlobalHasOwnProperty() { valueOf(); }
+
+assertEquals(Object.prototype, Object.prototype.valueOf());
+assertThrows(callGlobalValueOf);
+assertThrows(callGlobalHasOwnProperty);
+
+%OptimizeFunctionOnNextCall(Object.prototype.valueOf);
+Object.prototype.valueOf();
+
+assertEquals(Object.prototype, Object.prototype.valueOf());
+assertThrows(callGlobalValueOf);
+assertThrows(callGlobalHasOwnProperty);
+
+function CheckExceptionCallLocal() {
+ var valueOf = Object.prototype.valueOf;
+ var hasOwnProperty = Object.prototype.hasOwnProperty;
+ try { valueOf(); assertUnreachable(); } catch(e) { }
+ try { hasOwnProperty(); assertUnreachable(); } catch(e) { }
+}
+CheckExceptionCallLocal();
+
+function CheckExceptionCallParameter(f) {
+ try { f(); assertUnreachable(); } catch(e) { }
+}
+CheckExceptionCallParameter(Object.prototype.valueOf);
+CheckExceptionCallParameter(Object.prototype.hasOwnProperty);
var global2 = (function(){return this;})();
assertEquals(global, global2, "direct call to local function returns global");
-var builtin = Object.prototype.valueOf; // Builtin function that returns this.
-
-assertEquals(global, builtin(), "Direct call to builtin");
-
-
// Builtin that depends on value of this to compute result.
var builtin2 = Object.prototype.toString;
# This section is for tests that fail in both V8 and JSC. Thus they
# have been determined to be incompatible between Mozilla and V8/JSC.
+# Fail because it calls builtins as functions and do not expect the
+# builtin to have undefined as the receiver.
+ecma/String/15.5.4.6-2: FAIL_OK
+
# Fail because of toLowerCase and toUpperCase conversion.
ecma/String/15.5.4.11-2: FAIL_OK
ecma/String/15.5.4.11-5: FAIL_OK
S9.9_A1: FAIL_OK
S9.9_A2: FAIL_OK
+# Calls builtins without an explicit receiver which means that
+# undefined is passed to the builtin. The tests expect the global
+# object to be passed which was true in ES3 but not in ES5.
+S11.1.1_A2: FAIL_OK
+S15.5.4.4_A1_T3: FAIL_OK
+S15.5.4.5_A1_T3: FAIL_OK
+S15.5.4.6_A1_T3: FAIL_OK
+S15.5.4.7_A1_T3: FAIL_OK
+S15.5.4.8_A1_T3: FAIL_OK
+S15.5.4.9_A1_T3: FAIL_OK
+S15.5.4.10_A1_T3: FAIL_OK
+S15.5.4.11_A1_T3: FAIL_OK
+S15.5.4.12_A1_T3: FAIL_OK
+S15.5.4.13_A1_T3: FAIL_OK
+S15.5.4.14_A1_T3: FAIL_OK
+S15.5.4.15_A1_T3: FAIL_OK
+
##################### SKIPPED TESTS #####################
# These tests take a looong time to run in debug mode.