Commit e5f27966 authored by sgjesse@chromium.org's avatar sgjesse@chromium.org

Add fuzzing support for inline runtime functions

The inline runtime functions are now included in the fuzzing of the natives. The chack for the expected number of arguments passed have been moved to the parser which will generate a syntax error if a runtime function (either C++ or inline) is called with a different number of arguments than expected.
Review URL: http://codereview.chromium.org/573056

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@4096 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent b0c9738f
...@@ -3597,7 +3597,7 @@ void CodeGenerator::GenerateArgumentsLength(ZoneList<Expression*>* args) { ...@@ -3597,7 +3597,7 @@ void CodeGenerator::GenerateArgumentsLength(ZoneList<Expression*>* args) {
} }
void CodeGenerator::GenerateArgumentsAccess(ZoneList<Expression*>* args) { void CodeGenerator::GenerateArguments(ZoneList<Expression*>* args) {
VirtualFrame::SpilledScope spilled_scope; VirtualFrame::SpilledScope spilled_scope;
ASSERT(args->length() == 1); ASSERT(args->length() == 1);
......
...@@ -197,6 +197,10 @@ class CodeGenerator: public AstVisitor { ...@@ -197,6 +197,10 @@ class CodeGenerator: public AstVisitor {
static const int kUnknownIntValue = -1; static const int kUnknownIntValue = -1;
// If the name is an inline runtime function call return the number of
// expected arguments. Otherwise return -1.
static int InlineRuntimeCallArgumentsCount(Handle<String> name);
private: private:
// Construction/Destruction // Construction/Destruction
explicit CodeGenerator(MacroAssembler* masm); explicit CodeGenerator(MacroAssembler* masm);
...@@ -326,6 +330,7 @@ class CodeGenerator: public AstVisitor { ...@@ -326,6 +330,7 @@ class CodeGenerator: public AstVisitor {
struct InlineRuntimeLUT { struct InlineRuntimeLUT {
void (CodeGenerator::*method)(ZoneList<Expression*>*); void (CodeGenerator::*method)(ZoneList<Expression*>*);
const char* name; const char* name;
int nargs;
}; };
static InlineRuntimeLUT* FindInlineRuntimeLUT(Handle<String> name); static InlineRuntimeLUT* FindInlineRuntimeLUT(Handle<String> name);
...@@ -360,7 +365,7 @@ class CodeGenerator: public AstVisitor { ...@@ -360,7 +365,7 @@ class CodeGenerator: public AstVisitor {
// Support for arguments.length and arguments[?]. // Support for arguments.length and arguments[?].
void GenerateArgumentsLength(ZoneList<Expression*>* args); void GenerateArgumentsLength(ZoneList<Expression*>* args);
void GenerateArgumentsAccess(ZoneList<Expression*>* args); void GenerateArguments(ZoneList<Expression*>* args);
// Support for accessing the class and value fields of an object. // Support for accessing the class and value fields of an object.
void GenerateClassOf(ZoneList<Expression*>* args); void GenerateClassOf(ZoneList<Expression*>* args);
...@@ -396,14 +401,10 @@ class CodeGenerator: public AstVisitor { ...@@ -396,14 +401,10 @@ class CodeGenerator: public AstVisitor {
// Fast support for number to string. // Fast support for number to string.
void GenerateNumberToString(ZoneList<Expression*>* args); void GenerateNumberToString(ZoneList<Expression*>* args);
// Fast support for Math.pow(). // Fast call to math functions.
void GenerateMathPow(ZoneList<Expression*>* args); void GenerateMathPow(ZoneList<Expression*>* args);
// Fast call to sine function.
void GenerateMathSin(ZoneList<Expression*>* args); void GenerateMathSin(ZoneList<Expression*>* args);
void GenerateMathCos(ZoneList<Expression*>* args); void GenerateMathCos(ZoneList<Expression*>* args);
// Fast support for Math.pow().
void GenerateMathSqrt(ZoneList<Expression*>* args); void GenerateMathSqrt(ZoneList<Expression*>* args);
// Simple condition analysis. // Simple condition analysis.
......
...@@ -351,42 +351,18 @@ void CodeGenerator::ProcessDeclarations(ZoneList<Declaration*>* declarations) { ...@@ -351,42 +351,18 @@ void CodeGenerator::ProcessDeclarations(ZoneList<Declaration*>* declarations) {
} }
// List of special runtime calls which are generated inline. For some of these
// functions the code will be generated inline, and for others a call to a code
// stub will be inlined.
#define INLINE_RUNTIME_ENTRY(Name, argc, ressize) \
{&CodeGenerator::Generate##Name, "_" #Name, argc}, \
// Special cases: These 'runtime calls' manipulate the current
// frame and are only used 1 or two places, so we generate them
// inline instead of generating calls to them. They are used
// for implementing Function.prototype.call() and
// Function.prototype.apply().
CodeGenerator::InlineRuntimeLUT CodeGenerator::kInlineRuntimeLUT[] = { CodeGenerator::InlineRuntimeLUT CodeGenerator::kInlineRuntimeLUT[] = {
{&CodeGenerator::GenerateIsSmi, "_IsSmi"}, INLINE_RUNTIME_FUNCTION_LIST(INLINE_RUNTIME_ENTRY)
{&CodeGenerator::GenerateIsNonNegativeSmi, "_IsNonNegativeSmi"},
{&CodeGenerator::GenerateIsArray, "_IsArray"},
{&CodeGenerator::GenerateIsRegExp, "_IsRegExp"},
{&CodeGenerator::GenerateIsConstructCall, "_IsConstructCall"},
{&CodeGenerator::GenerateArgumentsLength, "_ArgumentsLength"},
{&CodeGenerator::GenerateArgumentsAccess, "_Arguments"},
{&CodeGenerator::GenerateClassOf, "_ClassOf"},
{&CodeGenerator::GenerateValueOf, "_ValueOf"},
{&CodeGenerator::GenerateSetValueOf, "_SetValueOf"},
{&CodeGenerator::GenerateFastCharCodeAt, "_FastCharCodeAt"},
{&CodeGenerator::GenerateCharFromCode, "_CharFromCode"},
{&CodeGenerator::GenerateObjectEquals, "_ObjectEquals"},
{&CodeGenerator::GenerateLog, "_Log"},
{&CodeGenerator::GenerateRandomPositiveSmi, "_RandomPositiveSmi"},
{&CodeGenerator::GenerateIsObject, "_IsObject"},
{&CodeGenerator::GenerateIsFunction, "_IsFunction"},
{&CodeGenerator::GenerateIsUndetectableObject, "_IsUndetectableObject"},
{&CodeGenerator::GenerateStringAdd, "_StringAdd"},
{&CodeGenerator::GenerateSubString, "_SubString"},
{&CodeGenerator::GenerateStringCompare, "_StringCompare"},
{&CodeGenerator::GenerateRegExpExec, "_RegExpExec"},
{&CodeGenerator::GenerateNumberToString, "_NumberToString"},
{&CodeGenerator::GenerateMathPow, "_Math_pow"},
{&CodeGenerator::GenerateMathSin, "_Math_sin"},
{&CodeGenerator::GenerateMathCos, "_Math_cos"},
{&CodeGenerator::GenerateMathSqrt, "_Math_sqrt"},
}; };
#undef INLINE_RUNTIME_ENTRY
CodeGenerator::InlineRuntimeLUT* CodeGenerator::FindInlineRuntimeLUT( CodeGenerator::InlineRuntimeLUT* CodeGenerator::FindInlineRuntimeLUT(
Handle<String> name) { Handle<String> name) {
...@@ -431,6 +407,14 @@ bool CodeGenerator::PatchInlineRuntimeEntry(Handle<String> name, ...@@ -431,6 +407,14 @@ bool CodeGenerator::PatchInlineRuntimeEntry(Handle<String> name,
} }
int CodeGenerator::InlineRuntimeCallArgumentsCount(Handle<String> name) {
CodeGenerator::InlineRuntimeLUT* f =
CodeGenerator::FindInlineRuntimeLUT(name);
if (f != NULL) return f->nargs;
return -1;
}
// Simple condition analysis. ALWAYS_TRUE and ALWAYS_FALSE represent a // Simple condition analysis. ALWAYS_TRUE and ALWAYS_FALSE represent a
// known result for the test expression, with no side effects. // known result for the test expression, with no side effects.
CodeGenerator::ConditionAnalysis CodeGenerator::AnalyzeCondition( CodeGenerator::ConditionAnalysis CodeGenerator::AnalyzeCondition(
......
...@@ -99,6 +99,36 @@ namespace v8 { ...@@ -99,6 +99,36 @@ namespace v8 {
namespace internal { namespace internal {
#define INLINE_RUNTIME_FUNCTION_LIST(F) \
F(IsSmi, 1, 1) \
F(IsNonNegativeSmi, 1, 1) \
F(IsArray, 1, 1) \
F(IsRegExp, 1, 1) \
F(IsConstructCall, 0, 1) \
F(ArgumentsLength, 0, 1) \
F(Arguments, 1, 1) \
F(ClassOf, 1, 1) \
F(ValueOf, 1, 1) \
F(SetValueOf, 2, 1) \
F(FastCharCodeAt, 2, 1) \
F(CharFromCode, 1, 1) \
F(ObjectEquals, 2, 1) \
F(Log, 3, 1) \
F(RandomPositiveSmi, 0, 1) \
F(IsObject, 1, 1) \
F(IsFunction, 1, 1) \
F(IsUndetectableObject, 1, 1) \
F(StringAdd, 2, 1) \
F(SubString, 3, 1) \
F(StringCompare, 2, 1) \
F(RegExpExec, 4, 1) \
F(NumberToString, 1, 1) \
F(MathPow, 2, 1) \
F(MathSin, 1, 1) \
F(MathCos, 1, 1) \
F(MathSqrt, 1, 1)
// Support for "structured" code comments. // Support for "structured" code comments.
#ifdef DEBUG #ifdef DEBUG
......
...@@ -5912,7 +5912,7 @@ void CodeGenerator::GenerateSetValueOf(ZoneList<Expression*>* args) { ...@@ -5912,7 +5912,7 @@ void CodeGenerator::GenerateSetValueOf(ZoneList<Expression*>* args) {
} }
void CodeGenerator::GenerateArgumentsAccess(ZoneList<Expression*>* args) { void CodeGenerator::GenerateArguments(ZoneList<Expression*>* args) {
ASSERT(args->length() == 1); ASSERT(args->length() == 1);
// ArgumentsAccessStub expects the key in edx and the formal // ArgumentsAccessStub expects the key in edx and the formal
......
...@@ -339,6 +339,10 @@ class CodeGenerator: public AstVisitor { ...@@ -339,6 +339,10 @@ class CodeGenerator: public AstVisitor {
bool in_spilled_code() const { return in_spilled_code_; } bool in_spilled_code() const { return in_spilled_code_; }
void set_in_spilled_code(bool flag) { in_spilled_code_ = flag; } void set_in_spilled_code(bool flag) { in_spilled_code_ = flag; }
// If the name is an inline runtime function call return the number of
// expected arguments. Otherwise return -1.
static int InlineRuntimeCallArgumentsCount(Handle<String> name);
private: private:
// Construction/Destruction // Construction/Destruction
explicit CodeGenerator(MacroAssembler* masm); explicit CodeGenerator(MacroAssembler* masm);
...@@ -522,6 +526,7 @@ class CodeGenerator: public AstVisitor { ...@@ -522,6 +526,7 @@ class CodeGenerator: public AstVisitor {
struct InlineRuntimeLUT { struct InlineRuntimeLUT {
void (CodeGenerator::*method)(ZoneList<Expression*>*); void (CodeGenerator::*method)(ZoneList<Expression*>*);
const char* name; const char* name;
int nargs;
}; };
static InlineRuntimeLUT* FindInlineRuntimeLUT(Handle<String> name); static InlineRuntimeLUT* FindInlineRuntimeLUT(Handle<String> name);
...@@ -555,7 +560,7 @@ class CodeGenerator: public AstVisitor { ...@@ -555,7 +560,7 @@ class CodeGenerator: public AstVisitor {
// Support for arguments.length and arguments[?]. // Support for arguments.length and arguments[?].
void GenerateArgumentsLength(ZoneList<Expression*>* args); void GenerateArgumentsLength(ZoneList<Expression*>* args);
void GenerateArgumentsAccess(ZoneList<Expression*>* args); void GenerateArguments(ZoneList<Expression*>* args);
// Support for accessing the class and value fields of an object. // Support for accessing the class and value fields of an object.
void GenerateClassOf(ZoneList<Expression*>* args); void GenerateClassOf(ZoneList<Expression*>* args);
...@@ -593,14 +598,10 @@ class CodeGenerator: public AstVisitor { ...@@ -593,14 +598,10 @@ class CodeGenerator: public AstVisitor {
// Fast support for number to string. // Fast support for number to string.
void GenerateNumberToString(ZoneList<Expression*>* args); void GenerateNumberToString(ZoneList<Expression*>* args);
// Fast support for Math.pow(). // Fast call to math functions.
void GenerateMathPow(ZoneList<Expression*>* args); void GenerateMathPow(ZoneList<Expression*>* args);
// Fast call to transcendental functions.
void GenerateMathSin(ZoneList<Expression*>* args); void GenerateMathSin(ZoneList<Expression*>* args);
void GenerateMathCos(ZoneList<Expression*>* args); void GenerateMathCos(ZoneList<Expression*>* args);
// Fast case for sqrt
void GenerateMathSqrt(ZoneList<Expression*>* args); void GenerateMathSqrt(ZoneList<Expression*>* args);
// Simple condition analysis. // Simple condition analysis.
......
// Copyright 2006-2008 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without // Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are // modification, are permitted provided that the following conditions are
// met: // met:
...@@ -85,7 +84,7 @@ function MathCeil(x) { ...@@ -85,7 +84,7 @@ function MathCeil(x) {
// ECMA 262 - 15.8.2.7 // ECMA 262 - 15.8.2.7
function MathCos(x) { function MathCos(x) {
if (!IS_NUMBER(x)) x = ToNumber(x); if (!IS_NUMBER(x)) x = ToNumber(x);
return %_Math_cos(x); return %_MathCos(x);
} }
// ECMA 262 - 15.8.2.8 // ECMA 262 - 15.8.2.8
...@@ -160,7 +159,7 @@ function MathMin(arg1, arg2) { // length == 2 ...@@ -160,7 +159,7 @@ function MathMin(arg1, arg2) { // length == 2
function MathPow(x, y) { function MathPow(x, y) {
if (!IS_NUMBER(x)) x = ToNumber(x); if (!IS_NUMBER(x)) x = ToNumber(x);
if (!IS_NUMBER(y)) y = ToNumber(y); if (!IS_NUMBER(y)) y = ToNumber(y);
return %_Math_pow(x, y); return %_MathPow(x, y);
} }
// ECMA 262 - 15.8.2.14 // ECMA 262 - 15.8.2.14
...@@ -177,13 +176,13 @@ function MathRound(x) { ...@@ -177,13 +176,13 @@ function MathRound(x) {
// ECMA 262 - 15.8.2.16 // ECMA 262 - 15.8.2.16
function MathSin(x) { function MathSin(x) {
if (!IS_NUMBER(x)) x = ToNumber(x); if (!IS_NUMBER(x)) x = ToNumber(x);
return %_Math_sin(x); return %_MathSin(x);
} }
// ECMA 262 - 15.8.2.17 // ECMA 262 - 15.8.2.17
function MathSqrt(x) { function MathSqrt(x) {
if (!IS_NUMBER(x)) x = ToNumber(x); if (!IS_NUMBER(x)) x = ToNumber(x);
return %_Math_sqrt(x); return %_MathSqrt(x);
} }
// ECMA 262 - 15.8.2.18 // ECMA 262 - 15.8.2.18
......
...@@ -182,7 +182,8 @@ function FormatMessage(message) { ...@@ -182,7 +182,8 @@ function FormatMessage(message) {
invalid_json: "String '%0' is not valid JSON", invalid_json: "String '%0' is not valid JSON",
circular_structure: "Converting circular structure to JSON", circular_structure: "Converting circular structure to JSON",
obj_ctor_property_non_object: "Object.%0 called on non-object", obj_ctor_property_non_object: "Object.%0 called on non-object",
array_indexof_not_defined: "Array.getIndexOf: Argument undefined" array_indexof_not_defined: "Array.getIndexOf: Argument undefined",
illegal_access: "illegal access"
}; };
} }
var format = kMessages[message.type]; var format = kMessages[message.type];
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include "api.h" #include "api.h"
#include "ast.h" #include "ast.h"
#include "bootstrapper.h" #include "bootstrapper.h"
#include "codegen.h"
#include "compiler.h" #include "compiler.h"
#include "messages.h" #include "messages.h"
#include "platform.h" #include "platform.h"
...@@ -3832,7 +3833,27 @@ Expression* Parser::ParseV8Intrinsic(bool* ok) { ...@@ -3832,7 +3833,27 @@ Expression* Parser::ParseV8Intrinsic(bool* ok) {
} }
} }
// Otherwise we have a runtime call. // Check that the expected number arguments are passed to runtime functions.
if (!is_pre_parsing_) {
if (function != NULL
&& function->nargs != -1
&& function->nargs != args->length()) {
ReportMessage("illegal_access", Vector<const char*>::empty());
*ok = false;
return NULL;
} else if (function == NULL && !name.is_null()) {
// If this is not a runtime function implemented in C++ it might be an
// inlined runtime function.
int argc = CodeGenerator::InlineRuntimeCallArgumentsCount(name);
if (argc != -1 && argc != args->length()) {
ReportMessage("illegal_access", Vector<const char*>::empty());
*ok = false;
return NULL;
}
}
}
// Otherwise we have a valid runtime call.
return NEW(CallRuntime(name, function, args)); return NEW(CallRuntime(name, function, args));
} }
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include "accessors.h" #include "accessors.h"
#include "api.h" #include "api.h"
#include "arguments.h" #include "arguments.h"
#include "codegen.h"
#include "compiler.h" #include "compiler.h"
#include "cpu.h" #include "cpu.h"
#include "dateparser-inl.h" #include "dateparser-inl.h"
...@@ -8665,18 +8666,28 @@ static Object* Runtime_ListNatives(Arguments args) { ...@@ -8665,18 +8666,28 @@ static Object* Runtime_ListNatives(Arguments args) {
HandleScope scope; HandleScope scope;
Handle<JSArray> result = Factory::NewJSArray(0); Handle<JSArray> result = Factory::NewJSArray(0);
int index = 0; int index = 0;
bool inline_runtime_functions = false;
#define ADD_ENTRY(Name, argc, ressize) \ #define ADD_ENTRY(Name, argc, ressize) \
{ \ { \
HandleScope inner; \ HandleScope inner; \
Handle<String> name = \ Handle<String> name; \
Factory::NewStringFromAscii( \ /* Inline runtime functions have an underscore in front of the name. */ \
Vector<const char>(#Name, StrLength(#Name))); \ if (inline_runtime_functions) { \
name = Factory::NewStringFromAscii( \
Vector<const char>("_" #Name, StrLength("_" #Name))); \
} else { \
name = Factory::NewStringFromAscii( \
Vector<const char>(#Name, StrLength(#Name))); \
} \
Handle<JSArray> pair = Factory::NewJSArray(0); \ Handle<JSArray> pair = Factory::NewJSArray(0); \
SetElement(pair, 0, name); \ SetElement(pair, 0, name); \
SetElement(pair, 1, Handle<Smi>(Smi::FromInt(argc))); \ SetElement(pair, 1, Handle<Smi>(Smi::FromInt(argc))); \
SetElement(result, index++, pair); \ SetElement(result, index++, pair); \
} }
inline_runtime_functions = false;
RUNTIME_FUNCTION_LIST(ADD_ENTRY) RUNTIME_FUNCTION_LIST(ADD_ENTRY)
inline_runtime_functions = true;
INLINE_RUNTIME_FUNCTION_LIST(ADD_ENTRY)
#undef ADD_ENTRY #undef ADD_ENTRY
return *result; return *result;
} }
......
...@@ -3600,7 +3600,7 @@ void CodeGenerator::VisitThisFunction(ThisFunction* node) { ...@@ -3600,7 +3600,7 @@ void CodeGenerator::VisitThisFunction(ThisFunction* node) {
} }
void CodeGenerator::GenerateArgumentsAccess(ZoneList<Expression*>* args) { void CodeGenerator::GenerateArguments(ZoneList<Expression*>* args) {
ASSERT(args->length() == 1); ASSERT(args->length() == 1);
// ArgumentsAccessStub expects the key in rdx and the formal // ArgumentsAccessStub expects the key in rdx and the formal
......
...@@ -337,6 +337,10 @@ class CodeGenerator: public AstVisitor { ...@@ -337,6 +337,10 @@ class CodeGenerator: public AstVisitor {
bool in_spilled_code() const { return in_spilled_code_; } bool in_spilled_code() const { return in_spilled_code_; }
void set_in_spilled_code(bool flag) { in_spilled_code_ = flag; } void set_in_spilled_code(bool flag) { in_spilled_code_ = flag; }
// If the name is an inline runtime function call return the number of
// expected arguments. Otherwise return -1.
static int InlineRuntimeCallArgumentsCount(Handle<String> name);
private: private:
// Construction/Destruction // Construction/Destruction
explicit CodeGenerator(MacroAssembler* masm); explicit CodeGenerator(MacroAssembler* masm);
...@@ -506,6 +510,7 @@ class CodeGenerator: public AstVisitor { ...@@ -506,6 +510,7 @@ class CodeGenerator: public AstVisitor {
struct InlineRuntimeLUT { struct InlineRuntimeLUT {
void (CodeGenerator::*method)(ZoneList<Expression*>*); void (CodeGenerator::*method)(ZoneList<Expression*>*);
const char* name; const char* name;
int nargs;
}; };
static InlineRuntimeLUT* FindInlineRuntimeLUT(Handle<String> name); static InlineRuntimeLUT* FindInlineRuntimeLUT(Handle<String> name);
bool CheckForInlineRuntimeCall(CallRuntime* node); bool CheckForInlineRuntimeCall(CallRuntime* node);
...@@ -537,7 +542,7 @@ class CodeGenerator: public AstVisitor { ...@@ -537,7 +542,7 @@ class CodeGenerator: public AstVisitor {
// Support for arguments.length and arguments[?]. // Support for arguments.length and arguments[?].
void GenerateArgumentsLength(ZoneList<Expression*>* args); void GenerateArgumentsLength(ZoneList<Expression*>* args);
void GenerateArgumentsAccess(ZoneList<Expression*>* args); void GenerateArguments(ZoneList<Expression*>* args);
// Support for accessing the class and value fields of an object. // Support for accessing the class and value fields of an object.
void GenerateClassOf(ZoneList<Expression*>* args); void GenerateClassOf(ZoneList<Expression*>* args);
...@@ -575,14 +580,10 @@ class CodeGenerator: public AstVisitor { ...@@ -575,14 +580,10 @@ class CodeGenerator: public AstVisitor {
// Fast support for number to string. // Fast support for number to string.
void GenerateNumberToString(ZoneList<Expression*>* args); void GenerateNumberToString(ZoneList<Expression*>* args);
// Fast support for Math.pow().
void GenerateMathPow(ZoneList<Expression*>* args);
// Fast call to math functions. // Fast call to math functions.
void GenerateMathPow(ZoneList<Expression*>* args);
void GenerateMathSin(ZoneList<Expression*>* args); void GenerateMathSin(ZoneList<Expression*>* args);
void GenerateMathCos(ZoneList<Expression*>* args); void GenerateMathCos(ZoneList<Expression*>* args);
// Fast case for sqrt
void GenerateMathSqrt(ZoneList<Expression*>* args); void GenerateMathSqrt(ZoneList<Expression*>* args);
// Simple condition analysis. // Simple condition analysis.
......
...@@ -232,10 +232,12 @@ class CodeGeneratorPatcher { ...@@ -232,10 +232,12 @@ class CodeGeneratorPatcher {
public: public:
CodeGeneratorPatcher() { CodeGeneratorPatcher() {
CodeGenerator::InlineRuntimeLUT genGetFramePointer = CodeGenerator::InlineRuntimeLUT genGetFramePointer =
{&CodeGenerator::GenerateGetFramePointer, "_GetFramePointer"}; {&CodeGenerator::GenerateGetFramePointer, "_GetFramePointer", 0};
// _FastCharCodeAt is not used in our tests. // _RandomPositiveSmi is not used in our tests. The one we replace need to
// have the same noumer of arguments as the one we put in, which is zero in
// this case.
bool result = CodeGenerator::PatchInlineRuntimeEntry( bool result = CodeGenerator::PatchInlineRuntimeEntry(
NewString("_FastCharCodeAt"), NewString("_RandomPositiveSmi"),
genGetFramePointer, &oldInlineEntry); genGetFramePointer, &oldInlineEntry);
CHECK(result); CHECK(result);
} }
......
...@@ -57,9 +57,17 @@ function makeFunction(name, argc) { ...@@ -57,9 +57,17 @@ function makeFunction(name, argc) {
return new Function(args.join(", "), "return %" + name + "(" + argsStr + ");"); return new Function(args.join(", "), "return %" + name + "(" + argsStr + ");");
} }
function testArgumentCount(name) { function testArgumentCount(name, argc) {
for (var i = 0; i < 10; i++) { for (var i = 0; i < 10; i++) {
var func = makeFunction(name, i); var func = null;
try {
func = makeFunction(name, i);
} catch (e) {
if (e != "SyntaxError: illegal access") throw e;
}
if (func === null && i == argc) {
throw "unexpected exception";
}
var args = [ ]; var args = [ ];
for (var j = 0; j < i; j++) for (var j = 0; j < i; j++)
args.push(0); args.push(0);
...@@ -176,7 +184,7 @@ function testNatives() { ...@@ -176,7 +184,7 @@ function testNatives() {
continue; continue;
print(name); print(name);
var argc = nativeInfo[1]; var argc = nativeInfo[1];
testArgumentCount(name); testArgumentCount(name, argc);
testArgumentTypes(name, argc); testArgumentTypes(name, argc);
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment