Skip to content

Commit fa6aa63

Browse files
vassilmladenovfacebook-github-bot
authored andcommitted
Reorder module exceptions and notices for string-to-class conversion + dynamically referenced
Summary: Class::resolve throws a module exception before returning the Class* used for the __DR check, but I misordered this in the JIT. String-to-class notice was raised before the module exception, since it doesn't actually need the Class* . This made it so class-ptr tests had a divergence between interp and jit mode when running w/ EnforceModules=2, DynamicallyReferenced...=1. Reorder the ClassGetC / FCallClsMethodM checks when cls input is string: - Class::resolve - Class::load -> Class* - module check (exn when EnforceModules=2) - DITCH checks: - Normal: raise str-to-class - ExplicitConversion: check __DR As a result, we no longer raise the str-to-class notice when the class doesn't exist Reviewed By: jtwarren Differential Revision: D71159208 fbshipit-source-id: ab135a99371745cca0d3ab8be42db0fb8381e919
1 parent 4fe72cd commit fa6aa63

14 files changed

+57
-52
lines changed

hphp/runtime/vm/bytecode.cpp

+3-4
Original file line numberDiff line numberDiff line change
@@ -979,9 +979,8 @@ static inline Class* classnameToClass(TypedValue* input) {
979979
if (tvIsString(input)) {
980980
auto const name = input->m_data.pstr;
981981
if (Class* class_ = Class::resolve(name, vmfp()->func())) {
982-
if (folly::Random::oneIn(Cfg::Eval::DynamicallyReferencedNoticeSampleRate) &&
983-
!class_->isDynamicallyReferenced()) {
984-
raise_notice(Strings::MISSING_DYNAMICALLY_REFERENCED, name->data());
982+
if (!class_->isDynamicallyReferenced()) {
983+
raiseMissingDynamicallyReferenced(class_);
985984
}
986985
return class_;
987986
}
@@ -1006,8 +1005,8 @@ static inline Class* classnameToClass(TypedValue* input) {
10061005
static inline Class* lookupClsRef(TypedValue* input) {
10071006
if (tvIsString(input)) {
10081007
auto const name = input->m_data.pstr;
1009-
raise_str_to_class_notice(name);
10101008
if (Class* class_ = Class::resolve(name, vmfp()->func())) {
1009+
raise_str_to_class_notice(name);
10111010
return class_;
10121011
}
10131012
raise_error(Strings::UNKNOWN_CLASS, name->data());

hphp/runtime/vm/jit/irgen-basic.cpp

+37-28
Original file line numberDiff line numberDiff line change
@@ -60,47 +60,56 @@ void emitClassGetC(IRGS& env, ClassGetCMode mode) {
6060
return;
6161
}
6262

63-
auto const cls = [&] {
63+
auto const fallback = [&] {
6464
switch (mode) {
6565
case ClassGetCMode::Normal:
66-
if (Cfg::Eval::RaiseStrToClsConversionNoticeSampleRate > 0
67-
&& name->isA(TStr)) {
68-
gen(env, RaiseStrToClassNotice, name);
69-
}
70-
return ldCls(env, name);
66+
return LdClsFallback::Fatal;
7167
case ClassGetCMode::ExplicitConversion:
7268
// HH\classname_to_class throws a catchable InvalidArgumentException
7369
// instead of raising a fatal error
7470
if (name->isA(TStr)) {
75-
auto const cls = ldCls(env, name, LdClsFallback::ThrowClassnameToClassString);
76-
if (Cfg::Eval::DynamicallyReferencedNoticeSampleRate > 0) {
77-
if (cls->hasConstVal() &&
78-
!cls->clsVal()->isDynamicallyReferenced()) {
79-
gen(env, RaiseMissingDynamicallyReferenced, cls);
80-
} else {
81-
ifThen(
82-
env,
83-
[&] (Block* taken) {
84-
auto const data = AttrData { AttrDynamicallyReferenced };
85-
gen(env, JmpZero, taken, gen(env, ClassHasAttr, data, cls));
86-
},
87-
[&] {
88-
hint(env, Block::Hint::Unlikely);
89-
gen(env, RaiseMissingDynamicallyReferenced, cls);
90-
}
91-
);
92-
}
93-
}
94-
return cls;
71+
return LdClsFallback::ThrowClassnameToClassString;
9572
} else { // TLazyCls
96-
return ldCls(env, name, LdClsFallback::ThrowClassnameToClassLazyClass);
73+
return LdClsFallback::ThrowClassnameToClassLazyClass;
9774
}
9875
}
9976
}();
77+
auto const cls = ldCls(env, name, fallback);
78+
79+
if (name->isA(TStr)) {
80+
emitModuleBoundaryCheck(env, cls, false);
81+
82+
switch (mode) {
83+
case ClassGetCMode::Normal:
84+
if (Cfg::Eval::RaiseStrToClsConversionNoticeSampleRate > 0) {
85+
gen(env, RaiseStrToClassNotice, name);
86+
}
87+
break;
88+
case ClassGetCMode::ExplicitConversion:
89+
if (Cfg::Eval::DynamicallyReferencedNoticeSampleRate > 0) {
90+
if (cls->hasConstVal() &&
91+
!cls->clsVal()->isDynamicallyReferenced()) {
92+
gen(env, RaiseMissingDynamicallyReferenced, cls);
93+
} else {
94+
ifThen(
95+
env,
96+
[&] (Block* taken) {
97+
auto const data = AttrData { AttrDynamicallyReferenced };
98+
gen(env, JmpZero, taken, gen(env, ClassHasAttr, data, cls));
99+
},
100+
[&] {
101+
hint(env, Block::Hint::Unlikely);
102+
gen(env, RaiseMissingDynamicallyReferenced, cls);
103+
}
104+
);
105+
}
106+
}
107+
break;
108+
}
109+
}
100110

101111
popC(env);
102112
decRef(env, name);
103-
if (name->isA(TStr)) emitModuleBoundaryCheck(env, cls, false);
104113
push(env, cls);
105114
}
106115

hphp/runtime/vm/jit/irgen-call.cpp

+8-6
Original file line numberDiff line numberDiff line change
@@ -470,7 +470,7 @@ void callProfiledFunc(IRGS& env, SSATmp* callee, SSATmp* objOrClass,
470470
return result;
471471
}();
472472

473-
speculateTargetFunction(env, callee, callKnown, callUnknown, choices,
473+
speculateTargetFunction(env, callee, callKnown, callUnknown, choices,
474474
0, Cfg::Jit::PGOCalledFuncCheckNumSpeculations);
475475
}
476476

@@ -2225,13 +2225,15 @@ void emitFCallClsMethodM(IRGS& env, FCallArgs fca, const StringData* clsHint,
22252225
}
22262226
auto const cls = [&] {
22272227
if (name->isA(TCls)) return name;
2228-
if (name->isA(TStr) &&
2229-
Cfg::Eval::RaiseStrToClsConversionNoticeSampleRate > 0) {
2230-
gen(env, RaiseStrToClassNotice, name);
2231-
}
22322228
auto const ret = name->isA(TObj) ?
22332229
gen(env, LdObjClass, name) : ldCls(env, name);
2234-
if (name->isA(TStr)) emitModuleBoundaryCheck(env, ret, false);
2230+
if (name->isA(TStr)) {
2231+
emitModuleBoundaryCheck(env, ret, false);
2232+
2233+
if(Cfg::Eval::RaiseStrToClsConversionNoticeSampleRate > 0) {
2234+
gen(env, RaiseStrToClassNotice, name);
2235+
}
2236+
}
22352237
decRef(env, name);
22362238
return ret;
22372239
}();

hphp/runtime/vm/jit/irlower-exception.cpp

-6
Original file line numberDiff line numberDiff line change
@@ -223,12 +223,6 @@ void cgRaiseForbiddenDynConstruct(IRLS& env, const IRInstruction* inst) {
223223
kVoidDest, SyncOptions::Sync, argGroup(env, inst).ssa(0));
224224
}
225225

226-
static void raiseMissingDynamicallyReferenced(const Class* cls) {
227-
if (folly::Random::oneIn(Cfg::Eval::DynamicallyReferencedNoticeSampleRate)) {
228-
raise_notice(Strings::MISSING_DYNAMICALLY_REFERENCED, cls->name()->data());
229-
}
230-
}
231-
232226
void cgRaiseMissingDynamicallyReferenced(IRLS& env, const IRInstruction* inst) {
233227
cgCallHelper(
234228
vmain(env),

hphp/runtime/vm/runtime.cpp

+7
Original file line numberDiff line numberDiff line change
@@ -554,6 +554,13 @@ void raiseDeploymentBoundaryViolation(const Class* cls) {
554554
}
555555
}
556556

557+
const StaticString s___DynamicallyReferenced("__DynamicallyReferenced");
558+
559+
void raiseMissingDynamicallyReferenced(const Class* cls) {
560+
if (folly::Random::oneIn(Cfg::Eval::DynamicallyReferencedNoticeSampleRate)) {
561+
raise_notice(Strings::MISSING_DYNAMICALLY_REFERENCED, cls->name()->data());
562+
}
563+
}
557564
//////////////////////////////////////////////////////////////////////
558565

559566
int64_t zero_error_level() {

hphp/runtime/vm/runtime.h

+2
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,8 @@ void raiseModulePropertyViolation(const Class* cls,
9999
void raiseDeploymentBoundaryViolation(const Func* callee);
100100
void raiseDeploymentBoundaryViolation(const Class* cls);
101101

102+
void raiseMissingDynamicallyReferenced(const Class* cls);
103+
102104
inline Iter*
103105
frame_iter(const ActRec* fp, int i) {
104106
return (Iter*)(uintptr_t(fp)
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
11
--inputs=__DIR__/module.inc
2-
-vRuntime.Eval.DynamicallyReferencedNoticeSampleRate=0
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
11
-vEval.EnforceModules=2
2-
-vEval.DynamicallyReferencedNoticeSampleRate=0
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,2 @@
11
--inputs=__DIR__/module-pair-a.inc
22
--inputs=__DIR__/module-pair-b-launder.inc
3-
-vRuntime.Eval.DynamicallyReferencedNoticeSampleRate=0
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
11
-vEval.EnforceModules=2
2-
-vEval.DynamicallyReferencedNoticeSampleRate=0
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,2 @@
11
--inputs=__DIR__/module-pair-a.inc
22
--inputs=__DIR__/module-pair-b.inc
3-
-vRuntime.Eval.DynamicallyReferencedNoticeSampleRate=0
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
11
-vEval.EnforceModules=2
2-
-vEval.DynamicallyReferencedNoticeSampleRate=0
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
11
--inputs=__DIR__/module.inc
2-
-vRuntime.Eval.DynamicallyReferencedNoticeSampleRate=0
-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
11
-vEval.EnforceModules=2
2-
-vEval.DynamicallyReferencedNoticeSampleRate=0

0 commit comments

Comments
 (0)